| 945 | def TransitiveGroups(d=None): |
| 946 | """ |
| 947 | INPUT: |
| 948 | |
| 949 | - ``d`` -- an integer (optional) |
| 950 | |
| 951 | Returns the set of all transitive groups of a given degree |
| 952 | ``d``. If ``d`` is not specified, it returns the set of all |
| 953 | transitive groups. |
| 954 | |
| 955 | Warning: TransitiveGroups requires the optional GAP database |
| 956 | package. Please install it with ``sage -i database_gap``. |
| 957 | |
| 958 | EXAMPLES:: |
| 959 | |
| 960 | sage: TransitiveGroups(3) |
| 961 | Transitive Groups of degree 3 |
| 962 | sage: TransitiveGroups(7) |
| 963 | Transitive Groups of degree 7 |
| 964 | sage: TransitiveGroups(8) |
| 965 | Transitive Groups of degree 8 |
| 966 | |
| 967 | sage: TransitiveGroups() |
| 968 | Transitive Groups |
| 969 | |
| 970 | .. warning:: in practice, the database currently only contains |
| 971 | transitive groups up to degree 30:: |
| 972 | |
| 973 | sage: TransitiveGroups(31).cardinality() # requires optional database_gap |
| 974 | Traceback (most recent call last): |
| 975 | ... |
| 976 | NotImplementedError: Only the transitive groups of order less than 30 are available in GAP's database |
| 977 | |
| 978 | """ |
| 979 | if d == None: |
| 980 | return TransitiveGroupsAll() |
| 981 | else: |
| 982 | d == Integer(d) |
| 983 | assert d >= 0, "A transitive group acts on a non negative integer number of positions" |
| 984 | return TransitiveGroupsOfDegree(d) |
| 985 | |
| 986 | class TransitiveGroupsAll(DisjointUnionEnumeratedSets): |
| 987 | """ |
| 988 | The infinite set of all transitive groups. |
| 989 | |
| 990 | EXAMPLES:: |
| 991 | |
| 992 | sage: L = TransitiveGroups(); L |
| 993 | Transitive Groups |
| 994 | sage: L.category() |
| 995 | Category of infinite enumerated sets |
| 996 | sage: L.cardinality() |
| 997 | +Infinity |
| 998 | |
| 999 | sage: p = L.__iter__() # requires optional database_gap |
| 1000 | sage: (p.next(), p.next(), p.next(), p.next(), p.next(), p.next(), p.next(), p.next()) # requires optional database_gap |
| 1001 | (Transitive group number 1 of degree 0, Transitive group number 1 of degree 1, Transitive group number 1 of degree 2, Transitive group number 1 of degree 3, Transitive group number 2 of degree 3, Transitive group number 1 of degree 4, Transitive group number 2 of degree 4, Transitive group number 3 of degree 4) |
| 1002 | |
| 1003 | TESTS:: |
| 1004 | |
| 1005 | sage: TestSuite(TransitiveGroups()).run() # requires optional database_gap # long time |
| 1006 | """ |
| 1007 | def __init__(self): |
| 1008 | """ |
| 1009 | TESTS:: |
| 1010 | |
| 1011 | sage: S = TransitiveGroups() # requires optional database_gap |
| 1012 | sage: S.category() # requires optional database_gap |
| 1013 | Category of infinite enumerated sets |
| 1014 | """ |
| 1015 | DisjointUnionEnumeratedSets.__init__(self, Family(NonNegativeIntegers(), lambda i: TransitiveGroups(i)) ) |
| 1016 | |
| 1017 | def _repr_(self): |
| 1018 | """ |
| 1019 | TESTS:: |
| 1020 | |
| 1021 | sage: TransitiveGroups() # requires optional database_gap # indirect doctest |
| 1022 | Transitive Groups |
| 1023 | """ |
| 1024 | return "Transitive Groups" |
| 1025 | |
| 1026 | def __contains__(self, G): |
| 1027 | r""" |
| 1028 | EXAMPLES:: |
| 1029 | |
| 1030 | sage: TransitiveGroup(5,2) in TransitiveGroups() # requires optional database_gap |
| 1031 | True |
| 1032 | sage: TransitiveGroup(6,5) in TransitiveGroups() # requires optional database_gap |
| 1033 | True |
| 1034 | sage: 1 in TransitiveGroups() # requires optional database_gap |
| 1035 | False |
| 1036 | """ |
| 1037 | return isinstance(G,TransitiveGroup) |
| 1038 | |
| 1039 | def _an_element_(self): |
| 1040 | """ |
| 1041 | Returns an element of ``self``. |
| 1042 | |
| 1043 | EXAMPLES:: |
| 1044 | |
| 1045 | sage: TransitiveGroups(5).an_element() # requires optional database_gap # indirect doctest |
| 1046 | Transitive group number 1 of degree 5 |
| 1047 | """ |
| 1048 | return TransitiveGroup(7,3) |
| 1049 | |
| 1050 | class TransitiveGroupsOfDegree(UniqueRepresentation, Parent): |
| 1051 | """ |
| 1052 | The set of all transitive groups of a given (small) degree. |
| 1053 | |
| 1054 | EXAMPLES:: |
| 1055 | |
| 1056 | sage: S = TransitiveGroups(4); S # requires optional database_gap |
| 1057 | Transitive Groups of degree 4 |
| 1058 | sage: list(S) # requires optional database_gap |
| 1059 | [Transitive group number 1 of degree 4, Transitive group number 2 of degree 4, Transitive group number 3 of degree 4, Transitive group number 4 of degree 4, Transitive group number 5 of degree 4] |
| 1060 | |
| 1061 | sage: TransitiveGroups(5).an_element() # requires optional database_gap |
| 1062 | Transitive group number 1 of degree 5 |
| 1063 | |
| 1064 | We write the cardinality of all transitive groups of degree 5:: |
| 1065 | |
| 1066 | sage: for G in TransitiveGroups(5): # requires optional database_gap |
| 1067 | ... print G.cardinality() |
| 1068 | 5 |
| 1069 | 10 |
| 1070 | 20 |
| 1071 | 60 |
| 1072 | 120 |
| 1073 | |
| 1074 | TESTS:: |
| 1075 | |
| 1076 | sage: TestSuite(TransitiveGroups(3)).run() # requires optional database_gap |
| 1077 | |
| 1078 | |
| 1079 | """ |
| 1080 | def __init__(self, n): |
| 1081 | """ |
| 1082 | TESTS:: |
| 1083 | |
| 1084 | sage: S = TransitiveGroups(4) # requires optional database_gap |
| 1085 | sage: S.category() # requires optional database_gap |
| 1086 | Category of finite enumerated sets |
| 1087 | """ |
| 1088 | self._degree = n |
| 1089 | Parent.__init__(self, category = FiniteEnumeratedSets()) |
| 1090 | |
| 1091 | def _repr_(self): |
| 1092 | """ |
| 1093 | TESTS:: |
| 1094 | |
| 1095 | sage: TransitiveGroups(6) # requires optional database_gap |
| 1096 | Transitive Groups of degree 6 |
| 1097 | """ |
| 1098 | return "Transitive Groups of degree %s"%(self._degree) |
| 1099 | |
| 1100 | def __contains__(self, G): |
| 1101 | r""" |
| 1102 | EXAMPLES:: |
| 1103 | |
| 1104 | sage: TransitiveGroup(6,5) in TransitiveGroups(4) # requires optional database_gap |
| 1105 | False |
| 1106 | sage: TransitiveGroup(4,3) in TransitiveGroups(4) # requires optional database_gap |
| 1107 | True |
| 1108 | sage: 1 in TransitiveGroups(4) # requires optional database_gap |
| 1109 | False |
| 1110 | """ |
| 1111 | if isinstance(G,TransitiveGroup): |
| 1112 | return G._d == self._degree |
| 1113 | else: |
| 1114 | False |
| 1115 | |
| 1116 | def __getitem__(self, n): |
| 1117 | r""" |
| 1118 | INPUT: |
| 1119 | |
| 1120 | - ``n`` -- a positive integer |
| 1121 | |
| 1122 | Returns the `n`-th transitive group of a given degree. |
| 1123 | |
| 1124 | EXAMPLES:: |
| 1125 | |
| 1126 | sage: TransitiveGroups(5)[3] # requires optional database_gap# |
| 1127 | Transitive group number 3 of degree 5 |
| 1128 | |
| 1129 | .. warning:: this follows GAP's naming convention of indexing |
| 1130 | the transitive groups starting from ``1``:: |
| 1131 | |
| 1132 | sage: TransitiveGroups(5)[0] |
| 1133 | Traceback (most recent call last): |
| 1134 | ... |
| 1135 | assert n > 0 |
| 1136 | AssertionError |
| 1137 | """ |
| 1138 | return TransitiveGroup(self._degree, n) |
| 1139 | |
| 1140 | def __iter__(self): |
| 1141 | """ |
| 1142 | EXAMPLES:: |
| 1143 | |
| 1144 | sage: list(TransitiveGroups(5)) # indirect doctest # requires optional database_gap |
| 1145 | [Transitive group number 1 of degree 5, Transitive group number 2 of degree 5, Transitive group number 3 of degree 5, Transitive group number 4 of degree 5, Transitive group number 5 of degree 5] |
| 1146 | """ |
| 1147 | for n in xrange(1, self.cardinality() + 1): |
| 1148 | yield self[n] |
| 1149 | |
| 1150 | _an_element_ = EnumeratedSets.ParentMethods._an_element_ |
| 1151 | |
| 1152 | @cached_method |
| 1153 | def cardinality(self): |
| 1154 | r""" |
| 1155 | Returns the cardinality of ``self``, that is the number of |
| 1156 | transitive groups of a given degree. |
| 1157 | |
| 1158 | EXAMPLES:: |
| 1159 | |
| 1160 | sage: TransitiveGroups(0).cardinality() # requires optional database_gap |
| 1161 | 1 |
| 1162 | sage: TransitiveGroups(2).cardinality() # requires optional database_gap |
| 1163 | 1 |
| 1164 | sage: TransitiveGroups(7).cardinality() # requires optional database_gap |
| 1165 | 7 |
| 1166 | sage: TransitiveGroups(12).cardinality() # requires optional database_gap |
| 1167 | 301 |
| 1168 | sage: [TransitiveGroups(i).cardinality() for i in range(11)] # requires optional database_gap |
| 1169 | [1, 1, 1, 2, 5, 5, 16, 7, 50, 34, 45] |
| 1170 | |
| 1171 | .. warning:: The database_gap contains all transitive groups |
| 1172 | up to degree 30:: |
| 1173 | |
| 1174 | sage: TransitiveGroups(31).cardinality() # requires optional database_gap |
| 1175 | Traceback (most recent call last): |
| 1176 | ... |
| 1177 | NotImplementedError: Only the transitive groups of order less than 30 are available in GAP's database |
| 1178 | |
| 1179 | TESTS:: |
| 1180 | |
| 1181 | sage: type(TransitiveGroups(12).cardinality()) # requires optional database_gap |
| 1182 | <type 'sage.rings.integer.Integer'> |
| 1183 | sage: type(TransitiveGroups(0).cardinality()) |
| 1184 | <type 'sage.rings.integer.Integer'> |
| 1185 | """ |
| 1186 | # gap.NrTransitiveGroups(0) fails, so Sage needs to handle this |
| 1187 | |
| 1188 | # While we are at it, and since Sage also handles the |
| 1189 | # transitive group of degree 1, we may as well handle 1 |
| 1190 | if self._degree <= 1: |
| 1191 | return ZZ(1) |
| 1192 | else: |
| 1193 | try: |
| 1194 | return Integer(gap.NrTransitiveGroups(gap(self._degree))) |
| 1195 | except RuntimeError: |
| 1196 | from sage.misc.misc import verbose |
| 1197 | verbose("Warning: TransitiveGroups requires the GAP database package. Please install it with ``sage -i database_gap``.", level=0) |
| 1198 | except TypeError: |
| 1199 | raise NotImplementedError, "Only the transitive groups of order less than 30 are available in GAP's database" |
| 1200 | |