passagemath-objects 10.6.47__cp311-cp311-macosx_13_0_x86_64.whl

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.
Files changed (280) hide show
  1. passagemath_objects/.dylibs/libgmp.10.dylib +0 -0
  2. passagemath_objects/__init__.py +3 -0
  3. passagemath_objects-10.6.47.dist-info/METADATA +115 -0
  4. passagemath_objects-10.6.47.dist-info/RECORD +280 -0
  5. passagemath_objects-10.6.47.dist-info/WHEEL +6 -0
  6. passagemath_objects-10.6.47.dist-info/top_level.txt +3 -0
  7. sage/all__sagemath_objects.py +37 -0
  8. sage/arith/all__sagemath_objects.py +5 -0
  9. sage/arith/long.pxd +411 -0
  10. sage/arith/numerical_approx.cpython-311-darwin.so +0 -0
  11. sage/arith/numerical_approx.pxd +35 -0
  12. sage/arith/numerical_approx.pyx +75 -0
  13. sage/arith/power.cpython-311-darwin.so +0 -0
  14. sage/arith/power.pxd +31 -0
  15. sage/arith/power.pyx +127 -0
  16. sage/categories/action.cpython-311-darwin.so +0 -0
  17. sage/categories/action.pxd +29 -0
  18. sage/categories/action.pyx +641 -0
  19. sage/categories/algebra_functor.py +745 -0
  20. sage/categories/all__sagemath_objects.py +33 -0
  21. sage/categories/basic.py +62 -0
  22. sage/categories/cartesian_product.py +295 -0
  23. sage/categories/category.py +3401 -0
  24. sage/categories/category_cy_helper.cpython-311-darwin.so +0 -0
  25. sage/categories/category_cy_helper.pxd +8 -0
  26. sage/categories/category_cy_helper.pyx +322 -0
  27. sage/categories/category_singleton.cpython-311-darwin.so +0 -0
  28. sage/categories/category_singleton.pxd +3 -0
  29. sage/categories/category_singleton.pyx +342 -0
  30. sage/categories/category_types.py +637 -0
  31. sage/categories/category_with_axiom.py +2876 -0
  32. sage/categories/covariant_functorial_construction.py +703 -0
  33. sage/categories/facade_sets.py +228 -0
  34. sage/categories/functor.cpython-311-darwin.so +0 -0
  35. sage/categories/functor.pxd +7 -0
  36. sage/categories/functor.pyx +691 -0
  37. sage/categories/homset.py +1338 -0
  38. sage/categories/homsets.py +364 -0
  39. sage/categories/isomorphic_objects.py +73 -0
  40. sage/categories/map.cpython-311-darwin.so +0 -0
  41. sage/categories/map.pxd +34 -0
  42. sage/categories/map.pyx +2106 -0
  43. sage/categories/morphism.cpython-311-darwin.so +0 -0
  44. sage/categories/morphism.pxd +14 -0
  45. sage/categories/morphism.pyx +895 -0
  46. sage/categories/objects.py +167 -0
  47. sage/categories/primer.py +1696 -0
  48. sage/categories/pushout.py +4834 -0
  49. sage/categories/quotients.py +64 -0
  50. sage/categories/realizations.py +200 -0
  51. sage/categories/sets_cat.py +3290 -0
  52. sage/categories/sets_with_partial_maps.py +52 -0
  53. sage/categories/subobjects.py +64 -0
  54. sage/categories/subquotients.py +21 -0
  55. sage/categories/with_realizations.py +311 -0
  56. sage/cpython/__init__.py +19 -0
  57. sage/cpython/_py2_random.py +619 -0
  58. sage/cpython/all.py +3 -0
  59. sage/cpython/atexit.cpython-311-darwin.so +0 -0
  60. sage/cpython/atexit.pyx +269 -0
  61. sage/cpython/builtin_types.cpython-311-darwin.so +0 -0
  62. sage/cpython/builtin_types.pyx +7 -0
  63. sage/cpython/cython_metaclass.cpython-311-darwin.so +0 -0
  64. sage/cpython/cython_metaclass.h +117 -0
  65. sage/cpython/cython_metaclass.pxd +3 -0
  66. sage/cpython/cython_metaclass.pyx +130 -0
  67. sage/cpython/debug.cpython-311-darwin.so +0 -0
  68. sage/cpython/debug.pyx +302 -0
  69. sage/cpython/dict_del_by_value.cpython-311-darwin.so +0 -0
  70. sage/cpython/dict_del_by_value.pxd +9 -0
  71. sage/cpython/dict_del_by_value.pyx +191 -0
  72. sage/cpython/dict_internal.h +245 -0
  73. sage/cpython/getattr.cpython-311-darwin.so +0 -0
  74. sage/cpython/getattr.pxd +9 -0
  75. sage/cpython/getattr.pyx +439 -0
  76. sage/cpython/pycore_long.h +97 -0
  77. sage/cpython/pycore_long.pxd +10 -0
  78. sage/cpython/python_debug.h +44 -0
  79. sage/cpython/python_debug.pxd +47 -0
  80. sage/cpython/pyx_visit.h +13 -0
  81. sage/cpython/string.cpython-311-darwin.so +0 -0
  82. sage/cpython/string.pxd +76 -0
  83. sage/cpython/string.pyx +34 -0
  84. sage/cpython/string_impl.h +60 -0
  85. sage/cpython/type.cpython-311-darwin.so +0 -0
  86. sage/cpython/type.pxd +2 -0
  87. sage/cpython/type.pyx +40 -0
  88. sage/cpython/wrapperdescr.pxd +67 -0
  89. sage/ext/all__sagemath_objects.py +3 -0
  90. sage/ext/ccobject.h +64 -0
  91. sage/ext/cplusplus.pxd +17 -0
  92. sage/ext/mod_int.h +30 -0
  93. sage/ext/mod_int.pxd +24 -0
  94. sage/ext/stdsage.pxd +39 -0
  95. sage/groups/all__sagemath_objects.py +1 -0
  96. sage/groups/group.cpython-311-darwin.so +0 -0
  97. sage/groups/group.pxd +14 -0
  98. sage/groups/group.pyx +322 -0
  99. sage/groups/old.cpython-311-darwin.so +0 -0
  100. sage/groups/old.pxd +14 -0
  101. sage/groups/old.pyx +219 -0
  102. sage/libs/all__sagemath_objects.py +3 -0
  103. sage/libs/gmp/__init__.py +1 -0
  104. sage/libs/gmp/all.pxd +6 -0
  105. sage/libs/gmp/binop.pxd +23 -0
  106. sage/libs/gmp/misc.pxd +8 -0
  107. sage/libs/gmp/mpf.pxd +88 -0
  108. sage/libs/gmp/mpn.pxd +57 -0
  109. sage/libs/gmp/mpq.pxd +57 -0
  110. sage/libs/gmp/mpz.pxd +202 -0
  111. sage/libs/gmp/pylong.cpython-311-darwin.so +0 -0
  112. sage/libs/gmp/pylong.pxd +12 -0
  113. sage/libs/gmp/pylong.pyx +150 -0
  114. sage/libs/gmp/random.pxd +25 -0
  115. sage/libs/gmp/randomize.pxd +59 -0
  116. sage/libs/gmp/types.pxd +53 -0
  117. sage/libs/gmpxx.pxd +19 -0
  118. sage/misc/abstract_method.py +276 -0
  119. sage/misc/all__sagemath_objects.py +43 -0
  120. sage/misc/bindable_class.py +253 -0
  121. sage/misc/c3_controlled.cpython-311-darwin.so +0 -0
  122. sage/misc/c3_controlled.pxd +2 -0
  123. sage/misc/c3_controlled.pyx +1402 -0
  124. sage/misc/cachefunc.cpython-311-darwin.so +0 -0
  125. sage/misc/cachefunc.pxd +43 -0
  126. sage/misc/cachefunc.pyx +3781 -0
  127. sage/misc/call.py +188 -0
  128. sage/misc/classcall_metaclass.cpython-311-darwin.so +0 -0
  129. sage/misc/classcall_metaclass.pxd +14 -0
  130. sage/misc/classcall_metaclass.pyx +599 -0
  131. sage/misc/constant_function.cpython-311-darwin.so +0 -0
  132. sage/misc/constant_function.pyx +130 -0
  133. sage/misc/decorators.py +747 -0
  134. sage/misc/fast_methods.cpython-311-darwin.so +0 -0
  135. sage/misc/fast_methods.pxd +20 -0
  136. sage/misc/fast_methods.pyx +351 -0
  137. sage/misc/flatten.py +90 -0
  138. sage/misc/fpickle.cpython-311-darwin.so +0 -0
  139. sage/misc/fpickle.pyx +177 -0
  140. sage/misc/function_mangling.cpython-311-darwin.so +0 -0
  141. sage/misc/function_mangling.pxd +11 -0
  142. sage/misc/function_mangling.pyx +308 -0
  143. sage/misc/inherit_comparison.cpython-311-darwin.so +0 -0
  144. sage/misc/inherit_comparison.pxd +5 -0
  145. sage/misc/inherit_comparison.pyx +105 -0
  146. sage/misc/instancedoc.cpython-311-darwin.so +0 -0
  147. sage/misc/instancedoc.pyx +331 -0
  148. sage/misc/lazy_attribute.cpython-311-darwin.so +0 -0
  149. sage/misc/lazy_attribute.pyx +607 -0
  150. sage/misc/lazy_format.py +135 -0
  151. sage/misc/lazy_import.cpython-311-darwin.so +0 -0
  152. sage/misc/lazy_import.pyx +1299 -0
  153. sage/misc/lazy_import_cache.py +36 -0
  154. sage/misc/lazy_list.cpython-311-darwin.so +0 -0
  155. sage/misc/lazy_list.pxd +19 -0
  156. sage/misc/lazy_list.pyx +1187 -0
  157. sage/misc/lazy_string.cpython-311-darwin.so +0 -0
  158. sage/misc/lazy_string.pxd +7 -0
  159. sage/misc/lazy_string.pyx +546 -0
  160. sage/misc/misc.py +1066 -0
  161. sage/misc/misc_c.cpython-311-darwin.so +0 -0
  162. sage/misc/misc_c.pxd +3 -0
  163. sage/misc/misc_c.pyx +766 -0
  164. sage/misc/namespace_package.py +37 -0
  165. sage/misc/nested_class.cpython-311-darwin.so +0 -0
  166. sage/misc/nested_class.pxd +3 -0
  167. sage/misc/nested_class.pyx +394 -0
  168. sage/misc/persist.cpython-311-darwin.so +0 -0
  169. sage/misc/persist.pyx +1251 -0
  170. sage/misc/prandom.py +418 -0
  171. sage/misc/randstate.cpython-311-darwin.so +0 -0
  172. sage/misc/randstate.pxd +30 -0
  173. sage/misc/randstate.pyx +1059 -0
  174. sage/misc/repr.py +203 -0
  175. sage/misc/reset.cpython-311-darwin.so +0 -0
  176. sage/misc/reset.pyx +196 -0
  177. sage/misc/sage_ostools.cpython-311-darwin.so +0 -0
  178. sage/misc/sage_ostools.pyx +323 -0
  179. sage/misc/sage_timeit.py +275 -0
  180. sage/misc/sage_timeit_class.cpython-311-darwin.so +0 -0
  181. sage/misc/sage_timeit_class.pyx +120 -0
  182. sage/misc/sage_unittest.py +637 -0
  183. sage/misc/sageinspect.py +2768 -0
  184. sage/misc/session.cpython-311-darwin.so +0 -0
  185. sage/misc/session.pyx +392 -0
  186. sage/misc/superseded.py +557 -0
  187. sage/misc/test_nested_class.py +228 -0
  188. sage/misc/timing.py +264 -0
  189. sage/misc/unknown.py +222 -0
  190. sage/misc/verbose.py +253 -0
  191. sage/misc/weak_dict.cpython-311-darwin.so +0 -0
  192. sage/misc/weak_dict.pxd +15 -0
  193. sage/misc/weak_dict.pyx +1231 -0
  194. sage/modules/all__sagemath_objects.py +1 -0
  195. sage/modules/module.cpython-311-darwin.so +0 -0
  196. sage/modules/module.pxd +5 -0
  197. sage/modules/module.pyx +329 -0
  198. sage/rings/all__sagemath_objects.py +3 -0
  199. sage/rings/integer_fake.h +22 -0
  200. sage/rings/integer_fake.pxd +55 -0
  201. sage/sets/all__sagemath_objects.py +3 -0
  202. sage/sets/pythonclass.cpython-311-darwin.so +0 -0
  203. sage/sets/pythonclass.pxd +9 -0
  204. sage/sets/pythonclass.pyx +247 -0
  205. sage/structure/__init__.py +4 -0
  206. sage/structure/all.py +30 -0
  207. sage/structure/category_object.cpython-311-darwin.so +0 -0
  208. sage/structure/category_object.pxd +28 -0
  209. sage/structure/category_object.pyx +1087 -0
  210. sage/structure/coerce.cpython-311-darwin.so +0 -0
  211. sage/structure/coerce.pxd +44 -0
  212. sage/structure/coerce.pyx +2107 -0
  213. sage/structure/coerce_actions.cpython-311-darwin.so +0 -0
  214. sage/structure/coerce_actions.pxd +27 -0
  215. sage/structure/coerce_actions.pyx +988 -0
  216. sage/structure/coerce_dict.cpython-311-darwin.so +0 -0
  217. sage/structure/coerce_dict.pxd +51 -0
  218. sage/structure/coerce_dict.pyx +1557 -0
  219. sage/structure/coerce_exceptions.py +23 -0
  220. sage/structure/coerce_maps.cpython-311-darwin.so +0 -0
  221. sage/structure/coerce_maps.pxd +28 -0
  222. sage/structure/coerce_maps.pyx +718 -0
  223. sage/structure/debug_options.cpython-311-darwin.so +0 -0
  224. sage/structure/debug_options.pxd +6 -0
  225. sage/structure/debug_options.pyx +54 -0
  226. sage/structure/dynamic_class.py +541 -0
  227. sage/structure/element.cpython-311-darwin.so +0 -0
  228. sage/structure/element.pxd +272 -0
  229. sage/structure/element.pyx +4772 -0
  230. sage/structure/element_wrapper.cpython-311-darwin.so +0 -0
  231. sage/structure/element_wrapper.pxd +12 -0
  232. sage/structure/element_wrapper.pyx +582 -0
  233. sage/structure/factorization.py +1422 -0
  234. sage/structure/factorization_integer.py +105 -0
  235. sage/structure/factory.cpython-311-darwin.so +0 -0
  236. sage/structure/factory.pyx +786 -0
  237. sage/structure/formal_sum.py +489 -0
  238. sage/structure/gens_py.py +73 -0
  239. sage/structure/global_options.py +1743 -0
  240. sage/structure/indexed_generators.py +863 -0
  241. sage/structure/list_clone.cpython-311-darwin.so +0 -0
  242. sage/structure/list_clone.pxd +65 -0
  243. sage/structure/list_clone.pyx +1867 -0
  244. sage/structure/list_clone_demo.cpython-311-darwin.so +0 -0
  245. sage/structure/list_clone_demo.pyx +248 -0
  246. sage/structure/list_clone_timings.py +179 -0
  247. sage/structure/list_clone_timings_cy.cpython-311-darwin.so +0 -0
  248. sage/structure/list_clone_timings_cy.pyx +86 -0
  249. sage/structure/mutability.cpython-311-darwin.so +0 -0
  250. sage/structure/mutability.pxd +21 -0
  251. sage/structure/mutability.pyx +348 -0
  252. sage/structure/nonexact.py +69 -0
  253. sage/structure/parent.cpython-311-darwin.so +0 -0
  254. sage/structure/parent.pxd +112 -0
  255. sage/structure/parent.pyx +3093 -0
  256. sage/structure/parent_base.cpython-311-darwin.so +0 -0
  257. sage/structure/parent_base.pxd +13 -0
  258. sage/structure/parent_base.pyx +44 -0
  259. sage/structure/parent_gens.cpython-311-darwin.so +0 -0
  260. sage/structure/parent_gens.pxd +22 -0
  261. sage/structure/parent_gens.pyx +377 -0
  262. sage/structure/parent_old.cpython-311-darwin.so +0 -0
  263. sage/structure/parent_old.pxd +25 -0
  264. sage/structure/parent_old.pyx +294 -0
  265. sage/structure/proof/__init__.py +1 -0
  266. sage/structure/proof/all.py +243 -0
  267. sage/structure/proof/proof.py +300 -0
  268. sage/structure/richcmp.cpython-311-darwin.so +0 -0
  269. sage/structure/richcmp.pxd +213 -0
  270. sage/structure/richcmp.pyx +495 -0
  271. sage/structure/sage_object.cpython-311-darwin.so +0 -0
  272. sage/structure/sage_object.pxd +3 -0
  273. sage/structure/sage_object.pyx +988 -0
  274. sage/structure/sage_object_test.py +19 -0
  275. sage/structure/sequence.py +937 -0
  276. sage/structure/set_factories.py +1178 -0
  277. sage/structure/set_factories_example.py +527 -0
  278. sage/structure/support_view.py +179 -0
  279. sage/structure/test_factory.py +56 -0
  280. sage/structure/unique_representation.py +1359 -0
@@ -0,0 +1,863 @@
1
+ # sage_setup: distribution = sagemath-objects
2
+ """
3
+ Indexed Generators
4
+ """
5
+ # ****************************************************************************
6
+ # Copyright (C) 2013 Travis Scrimshaw <tcscrims at gmail.com>
7
+ #
8
+ # This program is free software: you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation, either version 2 of the License, or
11
+ # (at your option) any later version.
12
+ # https://www.gnu.org/licenses/
13
+ # ****************************************************************************
14
+ from sage.structure.category_object import normalize_names
15
+
16
+
17
+ class IndexedGenerators:
18
+ r"""nodetex
19
+ Abstract base class for parents whose elements consist of generators
20
+ indexed by an arbitrary set.
21
+
22
+ Options controlling the printing of elements:
23
+
24
+ - ``prefix`` -- string, prefix used for printing elements of this
25
+ module (default: ``'x'``). With the default, a monomial
26
+ indexed by 'a' would be printed as ``x['a']``.
27
+
28
+ - ``latex_prefix`` -- string or ``None``, prefix used in the `\LaTeX`
29
+ representation of elements (default: ``None``); if this is
30
+ anything except the empty string, it prints the index as a
31
+ subscript. If this is ``None``, it uses the setting for ``prefix``,
32
+ so if ``prefix`` is set to "B", then a monomial indexed by 'a'
33
+ would be printed as ``B_{a}``. If this is the empty string, then
34
+ don't print monomials as subscripts: the monomial indexed by 'a'
35
+ would be printed as ``a``, or as ``[a]`` if ``latex_bracket`` is
36
+ ``True``.
37
+
38
+ - ``names`` -- dictionary with strings as values or list of strings (optional);
39
+ a mapping from the indices of the generators to strings giving the
40
+ generators explicit names. This is used instead of the print options
41
+ ``prefix`` and ``bracket`` when ``names`` is specified.
42
+
43
+ - ``latex_names`` -- dictionary with strings as values or list of strings
44
+ (optional); same as ``names`` except using the `\LaTeX` representation
45
+
46
+ - ``bracket`` -- ``None``, boolean, string, or list or tuple of
47
+ strings (default: ``None``); if ``None``, use the value of the
48
+ attribute ``self._repr_option_bracket``, which has default value
49
+ ``True``. (``self._repr_option_bracket`` is available for backwards
50
+ compatibility. Users should set ``bracket`` instead. If
51
+ ``bracket`` is set to anything except ``None``, it overrides
52
+ the value of ``self._repr_option_bracket``.) If ``False``, do not
53
+ include brackets when printing elements: a monomial indexed by
54
+ 'a' would be printed as ``B'a'``, and a monomial indexed by
55
+ (1,2,3) would be printed as ``B(1,2,3)``. If ``True``, use "[" and
56
+ "]" as brackets. If it is one of "[", "(", or "{", use it and
57
+ its partner as brackets. If it is any other string, use it as
58
+ both brackets. If it is a list or tuple of strings, use the
59
+ first entry as the left bracket and the second entry as the
60
+ right bracket.
61
+
62
+ - ``latex_bracket`` -- boolean, string, or list or tuple of strings
63
+ (default: ``False``); if ``False``, do not include brackets in
64
+ the LaTeX representation of elements. This option is only
65
+ relevant if ``latex_prefix`` is the empty string; otherwise,
66
+ brackets are not used regardless. If ``True``, use "\left[" and
67
+ "\right]" as brackets. If this is one of "[", "(", "\\{", "|",
68
+ or "||", use it and its partner, prepended with "\left" and
69
+ "\right", as brackets. If this is any other string, use it as
70
+ both brackets. If this is a list or tuple of strings, use the
71
+ first entry as the left bracket and the second entry as the
72
+ right bracket.
73
+
74
+ - ``scalar_mult`` -- string to use for scalar multiplication in
75
+ the print representation (default: ``'*'``)
76
+
77
+ - ``latex_scalar_mult`` -- string or ``None`` (default: ``None``);
78
+ string to use for scalar multiplication in the latex
79
+ representation. If ``None``, use the empty string if ``scalar_mult``
80
+ is set to "*", otherwise use the value of ``scalar_mult``.
81
+
82
+ - ``tensor_symbol`` -- string or ``None`` (default: ``None``);
83
+ string to use for tensor product in the print representation. If
84
+ ``None``, use ``sage.categories.tensor.symbol`` and
85
+ ``sage.categories.tensor.unicode_symbol``.
86
+
87
+ - ``sorting_key`` -- a key function (default: ``lambda x: x``);
88
+ to use for sorting elements in the output of elements
89
+
90
+ - ``sorting_reverse`` -- boolean (default: ``False``); if ``True``
91
+ sort elements in reverse order in the output of elements
92
+
93
+ - ``string_quotes`` -- boolean (default: ``True``); if ``True`` then
94
+ display string indices with quotes
95
+
96
+ - ``iterate_key`` -- boolean (default: ``False``); iterate through
97
+ the elements of the key and print the result as comma separated
98
+ objects for string output
99
+
100
+ .. NOTE::
101
+
102
+ These print options may also be accessed and modified using the
103
+ :meth:`print_options` method, after the parent has been defined.
104
+
105
+ EXAMPLES:
106
+
107
+ We demonstrate a variety of the input options::
108
+
109
+ sage: from sage.structure.indexed_generators import IndexedGenerators
110
+ sage: I = IndexedGenerators(ZZ, prefix='A')
111
+ sage: I._repr_generator(2)
112
+ 'A[2]'
113
+ sage: I._latex_generator(2)
114
+ 'A_{2}'
115
+
116
+ sage: I = IndexedGenerators(ZZ, bracket='(')
117
+ sage: I._repr_generator(2)
118
+ 'x(2)'
119
+ sage: I._latex_generator(2)
120
+ 'x_{2}'
121
+
122
+ sage: I = IndexedGenerators(ZZ, prefix='', latex_bracket='(')
123
+ sage: I._repr_generator(2)
124
+ '[2]'
125
+ sage: I._latex_generator(2)
126
+ \left( 2 \right)
127
+
128
+ sage: I = IndexedGenerators(ZZ, bracket=['|', '>'])
129
+ sage: I._repr_generator(2)
130
+ 'x|2>'
131
+ """
132
+ def __init__(self, indices, prefix='x', **kwds):
133
+ """
134
+ Initialize ``self``.
135
+
136
+ EXAMPLES:
137
+
138
+ This is a mixin class, so don't need pickling equality::
139
+
140
+ sage: I = sage.structure.indexed_generators.IndexedGenerators(ZZ)
141
+ sage: TestSuite(I).run(skip='_test_pickling')
142
+ """
143
+ self._indices = indices
144
+
145
+ # printing options for elements (set when initializing self).
146
+ # This includes self._repr_option_bracket (kept for backwards
147
+ # compatibility, declared to be True by default, needs to be
148
+ # overridden explicitly).
149
+ self._print_options = {'prefix': prefix,
150
+ 'names': None,
151
+ 'bracket': None,
152
+ 'latex_bracket': False,
153
+ 'latex_prefix': None,
154
+ 'latex_names': None,
155
+ 'scalar_mult': "*",
156
+ 'latex_scalar_mult': None,
157
+ 'tensor_symbol': None,
158
+ 'string_quotes': True,
159
+ 'sorting_key': lambda x: x,
160
+ 'sorting_reverse': False,
161
+ 'iterate_key': False}
162
+ # 'bracket': its default value here is None, meaning that
163
+ # the value of self._repr_option_bracket is used; the default
164
+ # value of that attribute is True -- see immediately before
165
+ # the method _repr_generator. If 'bracket' is any value
166
+ # except None, then it overrides the value of
167
+ # self._repr_option_bracket. Future users might consider
168
+ # using 'bracket' instead of _repr_option_bracket.
169
+ self.print_options(**kwds)
170
+
171
+ def indices(self):
172
+ """
173
+ Return the indices of ``self``.
174
+
175
+ EXAMPLES::
176
+
177
+ sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) # needs sage.modules
178
+ sage: F.indices() # needs sage.modules
179
+ {'a', 'b', 'c'}
180
+ """
181
+ return self._indices
182
+
183
+ def prefix(self):
184
+ """
185
+ Return the prefix used when displaying elements of ``self``.
186
+
187
+ EXAMPLES::
188
+
189
+ sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) # needs sage.modules
190
+ sage: F.prefix() # needs sage.modules
191
+ 'B'
192
+
193
+ ::
194
+
195
+ sage: X = SchubertPolynomialRing(QQ) # needs sage.combinat sage.modules
196
+ sage: X.prefix() # needs sage.combinat sage.modules
197
+ 'X'
198
+ """
199
+ return self._print_options['prefix']
200
+
201
+ def print_options(self, **kwds):
202
+ """
203
+ Return the current print options, or set an option.
204
+
205
+ INPUT:
206
+
207
+ All of the input is optional; if present, it should be
208
+ in the form of keyword pairs, such as
209
+ ``latex_bracket='('``. The allowable keywords are:
210
+
211
+ - ``prefix``
212
+ - ``latex_prefix``
213
+ - ``names``
214
+ - ``latex_names``
215
+ - ``bracket``
216
+ - ``latex_bracket``
217
+ - ``scalar_mult``
218
+ - ``latex_scalar_mult``
219
+ - ``tensor_symbol``
220
+ - ``string_quotes``
221
+ - ``sorting_key``
222
+ - ``sorting_reverse``
223
+ - ``iterate_key``
224
+
225
+ See the documentation for :class:`IndexedGenerators` for
226
+ descriptions of the effects of setting each of these options.
227
+
228
+ OUTPUT: if the user provides any input, set the appropriate
229
+ option(s) and return nothing. Otherwise, return the
230
+ dictionary of settings for print and LaTeX representations.
231
+
232
+ EXAMPLES::
233
+
234
+ sage: # needs sage.modules
235
+ sage: F = CombinatorialFreeModule(ZZ, [1,2,3], prefix='x')
236
+ sage: F.print_options()
237
+ {...'prefix': 'x'...}
238
+ sage: F.print_options(bracket='(')
239
+ sage: F.print_options()
240
+ {...'bracket': '('...}
241
+
242
+ TESTS::
243
+
244
+ sage: sorted(F.print_options().items()) # needs sage.modules
245
+ [('bracket', '('), ('iterate_key', False),
246
+ ('latex_bracket', False), ('latex_names', None),
247
+ ('latex_prefix', None), ('latex_scalar_mult', None),
248
+ ('names', None), ('prefix', 'x'),
249
+ ('scalar_mult', '*'),
250
+ ('sorting_key', <function ...<lambda> at ...>),
251
+ ('sorting_reverse', False), ('string_quotes', True),
252
+ ('tensor_symbol', None)]
253
+ sage: F.print_options(bracket='[') # reset # needs sage.modules
254
+ """
255
+ # don't just use kwds.get(...) because I want to distinguish
256
+ # between an argument like "option=None" and the option not
257
+ # being there altogether.
258
+ if kwds:
259
+ for option in kwds:
260
+ if option in self._print_options:
261
+ self._print_options[option] = kwds[option]
262
+ else:
263
+ raise ValueError('{} is not a valid print option.'.format(option))
264
+ return
265
+ return self._print_options
266
+
267
+ _repr_option_bracket = True
268
+
269
+ def _parse_names(self, m, use_latex):
270
+ """
271
+ Return the name corresponding to ``m`` if it exists,
272
+ otherwise return ``None``.
273
+
274
+ EXAMPLES::
275
+
276
+ sage: F = CombinatorialFreeModule(ZZ, [1,2,3], names='a,b,c', # needs sage.modules
277
+ ....: latex_names='x,y,z')
278
+ sage: F._parse_names(1, False) # needs sage.modules
279
+ 'a'
280
+ sage: F._parse_names(1, True) # needs sage.modules
281
+ 'x'
282
+
283
+ sage: F.print_options(latex_names=None) # needs sage.modules
284
+ sage: F._parse_names(1, True) # needs sage.modules
285
+ 'a'
286
+
287
+ sage: # needs sage.modules
288
+ sage: F.print_options(latex_names={1:'x', 2:'y'}, names=None)
289
+ sage: F._parse_names(1, False) is None
290
+ True
291
+ sage: F._parse_names(1, True)
292
+ 'x'
293
+ sage: F._parse_names(3, True) is None
294
+ True
295
+
296
+ sage: # needs sage.modules
297
+ sage: F.print_options(names={1:'a', 3:'c'}, latex_names=None)
298
+ sage: F._parse_names(1, False)
299
+ 'a'
300
+ sage: F._parse_names(1, True)
301
+ 'a'
302
+ sage: F._parse_names(2, False) is None
303
+ True
304
+ sage: F._parse_names(2, True) is None
305
+ True
306
+ """
307
+ names = self._print_options.get('names', None)
308
+ if use_latex:
309
+ latex_names = self._print_options.get('latex_names', None)
310
+ if latex_names is not None:
311
+ names = latex_names
312
+
313
+ if names is not None:
314
+ if isinstance(names, dict):
315
+ try:
316
+ return names[m]
317
+ except KeyError:
318
+ return None
319
+ else: # treat it like a list
320
+ try:
321
+ i = self._indices.rank(m)
322
+ except (AttributeError, TypeError, KeyError, ValueError):
323
+ return None
324
+ if i >= len(names):
325
+ return None
326
+ try:
327
+ return names[i]
328
+ except (AttributeError, TypeError, KeyError, ValueError):
329
+ return None
330
+ return None
331
+
332
+ def _repr_generator(self, m):
333
+ """
334
+ Return a string representing the generator indexed by ``m``.
335
+
336
+ The output can be customized by setting any of the following
337
+ options when initializing the parent:
338
+
339
+ - ``prefix``
340
+ - ``bracket``
341
+ - ``scalar_mult``
342
+ - ``names``
343
+ - ``iterate_key``
344
+
345
+ Alternatively, one can use the :meth:`print_options` method
346
+ to achieve the same effect. To modify the bracket setting,
347
+ one can also set ``self._repr_option_bracket`` as long as one
348
+ has *not* set the ``bracket`` option: if the
349
+ ``bracket`` option is anything but ``None``, it overrides
350
+ the value of ``self._repr_option_bracket``.
351
+
352
+ See the documentation for :class:`CombinatorialFreeModule` for
353
+ details on the initialization options.
354
+
355
+ EXAMPLES::
356
+
357
+ sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) # needs sage.modules
358
+ sage: e = F.basis() # needs sage.modules
359
+ sage: e['a'] + 2*e['b'] # indirect doctest # needs sage.modules
360
+ B['a'] + 2*B['b']
361
+
362
+ sage: # needs sage.modules
363
+ sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c'], prefix='F')
364
+ sage: e = F.basis()
365
+ sage: e['a'] + 2*e['b'] # indirect doctest
366
+ F['a'] + 2*F['b']
367
+ sage: F.print_options(string_quotes=False)
368
+ sage: e['a'] + 2*e['b']
369
+ F[a] + 2*F[b]
370
+
371
+ sage: # needs sage.modules
372
+ sage: F = CombinatorialFreeModule(QQ, ['aa', 'bb', 'cc'], prefix='F')
373
+ sage: e = F.basis()
374
+ sage: F.print_options(iterate_key=True)
375
+ sage: e['aa'] + 2*e['bb']
376
+ F['a', 'a'] + 2*F['b', 'b']
377
+ sage: F.print_options(string_quotes=False)
378
+ sage: e['aa'] + 2*e['bb']
379
+ F[a, a] + 2*F[b, b]
380
+
381
+ sage: # needs sage.combinat sage.modules
382
+ sage: QS3 = CombinatorialFreeModule(QQ, Permutations(3), prefix="")
383
+ sage: original_print_options = QS3.print_options()
384
+ sage: a = 2*QS3([1,2,3])+4*QS3([3,2,1])
385
+ sage: a # indirect doctest
386
+ 2*[[1, 2, 3]] + 4*[[3, 2, 1]]
387
+
388
+ sage: QS3.print_options(bracket = False) # needs sage.combinat sage.modules
389
+ sage: a # indirect doctest # needs sage.combinat sage.modules
390
+ 2*[1, 2, 3] + 4*[3, 2, 1]
391
+
392
+ sage: QS3.print_options(prefix='') # needs sage.combinat sage.modules
393
+ sage: a # indirect doctest # needs sage.combinat sage.modules
394
+ 2*[1, 2, 3] + 4*[3, 2, 1]
395
+
396
+ sage: QS3.print_options(bracket="|", scalar_mult=" *@* ") # needs sage.combinat sage.modules
397
+ sage: a # indirect doctest # needs sage.combinat sage.modules
398
+ 2 *@* |[1, 2, 3]| + 4 *@* |[3, 2, 1]|
399
+
400
+ sage: QS3.print_options(bracket="|", scalar_mult="*", iterate_key=True) # needs sage.combinat sage.modules
401
+ sage: a # indirect doctest # needs sage.combinat sage.modules
402
+ 2*|1, 2, 3| + 4*|3, 2, 1|
403
+
404
+ sage: QS3.print_options(**original_print_options) # reset # needs sage.combinat sage.modules
405
+
406
+ TESTS::
407
+
408
+ sage: F = CombinatorialFreeModule(QQ, [('a', 'b'), ('c','d')]) # needs sage.modules
409
+ sage: e = F.basis() # needs sage.modules
410
+ sage: e[('a','b')] + 2*e[('c','d')] # indirect doctest # needs sage.modules
411
+ B[('a', 'b')] + 2*B[('c', 'd')]
412
+
413
+ sage: F.<a,b,c> = CombinatorialFreeModule(QQ) # needs sage.modules
414
+ sage: a + 2*b # needs sage.modules
415
+ a + 2*b
416
+
417
+ sage: # needs sage.modules
418
+ sage: F = CombinatorialFreeModule(QQ, ZZ)
419
+ sage: e = F.basis()
420
+ sage: 3*e[1] + 2*e[-2]
421
+ 2*B[-2] + 3*B[1]
422
+ sage: F.print_options(iterate_key=True)
423
+ sage: 3*e[1] + 2*e[-2]
424
+ 2*B[-2] + 3*B[1]
425
+ """
426
+ ret = self._parse_names(m, False)
427
+ if ret is not None:
428
+ return ret
429
+ bracket = self._print_options.get('bracket', None)
430
+ bracket_d = {"{": "}", "[": "]", "(": ")"}
431
+ if bracket is None:
432
+ bracket = self._repr_option_bracket
433
+ if bracket is True:
434
+ left = "["
435
+ right = "]"
436
+ elif bracket is False:
437
+ left = ""
438
+ right = ""
439
+ elif isinstance(bracket, (tuple, list)):
440
+ left = bracket[0]
441
+ right = bracket[1]
442
+ elif bracket in bracket_d:
443
+ left = bracket
444
+ right = bracket_d[bracket]
445
+ else:
446
+ left = bracket
447
+ right = bracket
448
+ iterate_key = self._print_options.get('iterate_key', False)
449
+ quotes = self._print_options.get('string_quotes', True)
450
+ if iterate_key:
451
+ try:
452
+ m = iter(m)
453
+ except TypeError:
454
+ pass # not iterable, so fallback to normal behavior
455
+ else:
456
+ if not quotes:
457
+ return self.prefix() + left + (', '.join(str(val) for val in m)) + right
458
+ return self.prefix() + left + (', '.join(repr(val) for val in m)) + right
459
+ if not quotes and isinstance(m, str):
460
+ return self.prefix() + left + m + right
461
+ return self.prefix() + left + repr(m) + right # mind the (m), to accept a tuple for m
462
+
463
+ def _ascii_art_generator(self, m):
464
+ r"""
465
+ Return an ascii art representing the generator indexed by ``m``.
466
+
467
+ TESTS::
468
+
469
+ sage: # needs sage.combinat sage.modules
470
+ sage: R = NonCommutativeSymmetricFunctions(QQ).R()
471
+ sage: ascii_art(R[1,2,2,4])
472
+ R
473
+ ****
474
+ **
475
+ **
476
+ *
477
+ sage: Partitions.options(diagram_str='#', convention='french')
478
+ sage: ascii_art(R[1,2,2,4])
479
+ R
480
+ #
481
+ ##
482
+ ##
483
+ ####
484
+ sage: Partitions.options._reset()
485
+
486
+ sage: F.<a,b,c> = CombinatorialFreeModule(QQ) # needs sage.modules
487
+ sage: ascii_art(a + 2*b) # needs sage.modules
488
+ a + 2*b
489
+ """
490
+ from sage.typeset.ascii_art import AsciiArt, ascii_art
491
+ ret = self._parse_names(m, False)
492
+ if ret is not None:
493
+ return ascii_art(ret)
494
+
495
+ pref = AsciiArt([self.prefix()])
496
+ if not pref:
497
+ return ascii_art(m)
498
+ r = pref * (AsciiArt([" " * len(pref)]) + ascii_art(m))
499
+ r._baseline = r._h - 1
500
+ return r
501
+
502
+ def _unicode_art_generator(self, m):
503
+ r"""
504
+ Return an unicode art representing the generator indexed by ``m``.
505
+
506
+ TESTS::
507
+
508
+ sage: # needs sage.combinat
509
+ sage: R = NonCommutativeSymmetricFunctions(QQ).R() # needs sage.modules
510
+ sage: unicode_art(R[1,2,2,4]) # needs sage.modules
511
+ R
512
+ ┌┬┬┬┐
513
+ ┌┼┼┴┴┘
514
+ ┌┼┼┘
515
+ ├┼┘
516
+ └┘
517
+ sage: Partitions.options.convention="french"
518
+ sage: unicode_art(R[1,2,2,4]) # needs sage.modules
519
+ R
520
+ ┌┐
521
+ ├┼┐
522
+ └┼┼┐
523
+ └┼┼┬┬┐
524
+ └┴┴┴┘
525
+ sage: Partitions.options._reset()
526
+
527
+ sage: F.<a,b,c> = CombinatorialFreeModule(QQ) # needs sage.modules
528
+ sage: unicode_art(a + 2*b) # needs sage.modules
529
+ a + 2*b
530
+ """
531
+ from sage.typeset.unicode_art import UnicodeArt, unicode_art
532
+ ret = self._parse_names(m, False)
533
+ if ret is not None:
534
+ return unicode_art(ret)
535
+
536
+ pref = UnicodeArt([self.prefix()])
537
+ if not pref:
538
+ return unicode_art(m)
539
+ r = pref * (UnicodeArt([" " * len(pref)]) + unicode_art(m))
540
+ r._baseline = r._h - 1
541
+ return r
542
+
543
+ def _latex_generator(self, m):
544
+ r"""
545
+ Return a `\LaTeX` for the generator indexed by ``m``.
546
+
547
+ The output can be customized by setting any of the following
548
+ options when initializing the parent:
549
+
550
+ - ``prefix``
551
+ - ``latex_prefix``
552
+ - ``latex_bracket``
553
+ - ``names``
554
+ - ``latex_names``
555
+
556
+ (Alternatively, one can use the :meth:`print_options` method
557
+ to achieve the same effect.)
558
+
559
+ See the documentation for :class:`CombinatorialFreeModule` for
560
+ details on the initialization options.
561
+
562
+ EXAMPLES::
563
+
564
+ sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) # needs sage.modules
565
+ sage: e = F.basis() # needs sage.modules
566
+ sage: latex(e['a'] + 2*e['b']) # indirect doctest # needs sage.modules
567
+ B_{a} + 2 B_{b}
568
+
569
+ sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c'], prefix='C') # needs sage.modules
570
+ sage: e = F.basis() # needs sage.modules
571
+ sage: latex(e['a'] + 2*e['b']) # indirect doctest # needs sage.modules
572
+ C_{a} + 2 C_{b}
573
+
574
+ sage: # needs sage.combinat sage.modules
575
+ sage: QS3 = CombinatorialFreeModule(QQ, Permutations(3),
576
+ ....: prefix='', scalar_mult='*')
577
+ sage: original_print_options = QS3.print_options()
578
+ sage: a = 2*QS3([1,2,3])+4*QS3([3,2,1])
579
+ sage: latex(a) # indirect doctest
580
+ 2 [1, 2, 3] + 4 [3, 2, 1]
581
+ sage: QS3.print_options(latex_bracket=True)
582
+ sage: latex(a) # indirect doctest
583
+ 2 \left[ [1, 2, 3] \right] + 4 \left[ [3, 2, 1] \right]
584
+ sage: QS3.print_options(latex_bracket="(")
585
+ sage: latex(a) # indirect doctest
586
+ 2 \left( [1, 2, 3] \right) + 4 \left( [3, 2, 1] \right)
587
+ sage: QS3.print_options(latex_bracket=('\\myleftbracket',
588
+ ....: '\\myrightbracket'))
589
+ sage: latex(a) # indirect doctest
590
+ 2 \myleftbracket [1, 2, 3] \myrightbracket + 4 \myleftbracket [3, 2, 1] \myrightbracket
591
+ sage: QS3.print_options(**original_print_options) # reset
592
+
593
+ TESTS::
594
+
595
+ sage: # needs sage.modules
596
+ sage: F = CombinatorialFreeModule(QQ, [('a', 'b'), (0,1,2)])
597
+ sage: e = F.basis()
598
+ sage: latex(e[('a','b')]) # indirect doctest
599
+ B_{('a', 'b')}
600
+ sage: latex(2*e[(0,1,2)]) # indirect doctest
601
+ 2 B_{\left(0, 1, 2\right)}
602
+ sage: F = CombinatorialFreeModule(QQ, [('a', 'b'), (0,1,2)], prefix="")
603
+ sage: e = F.basis()
604
+ sage: latex(2*e[(0,1,2)]) # indirect doctest
605
+ 2 \left(0, 1, 2\right)
606
+
607
+ sage: F.<a,b,c> = CombinatorialFreeModule(QQ, latex_names='x,y,z') # needs sage.modules
608
+ sage: latex(a + 2*b) # needs sage.modules
609
+ x + 2 y
610
+ """
611
+ from sage.misc.latex import latex
612
+
613
+ ret = self._parse_names(m, True)
614
+ if ret is not None:
615
+ return ret
616
+
617
+ s = latex(m)
618
+ if s.find('\\text{\\textt') != -1:
619
+ # m contains "non-LaTeXed" strings, use string representation
620
+ s = str(m)
621
+
622
+ # dictionary with left-right pairs of "brackets". put pairs
623
+ # in here accept \\left and \\right as prefixes.
624
+ bracket_d = {"{": "\\}", "[": "]", "(": ")", "\\{": "\\}",
625
+ "|": "|", "||": "||"}
626
+ bracket = self._print_options.get('latex_bracket', False)
627
+ if bracket is True:
628
+ left = "\\left["
629
+ right = "\\right]"
630
+ elif bracket is False:
631
+ left = ""
632
+ right = ""
633
+ elif isinstance(bracket, (tuple, list)):
634
+ left = bracket[0]
635
+ right = bracket[1]
636
+ elif bracket in bracket_d:
637
+ left = bracket
638
+ right = bracket_d[bracket]
639
+ if left == "{":
640
+ left = "\\{"
641
+ left = "\\left" + left
642
+ right = "\\right" + right
643
+ else:
644
+ left = bracket
645
+ right = bracket
646
+ prefix = self._print_options.get('latex_prefix')
647
+ if prefix is None:
648
+ prefix = self._print_options.get('prefix')
649
+ if prefix == "":
650
+ return left + s + right
651
+ return "%s_{%s}" % (prefix, s)
652
+
653
+
654
+ def split_index_keywords(kwds):
655
+ """
656
+ Split the dictionary ``kwds`` into two dictionaries, one containing
657
+ keywords for :class:`IndexedGenerators`, and the other is everything else.
658
+
659
+ OUTPUT:
660
+
661
+ The dictionary containing only they keywords
662
+ for :class:`IndexedGenerators`. This modifies the dictionary ``kwds``.
663
+
664
+ .. WARNING::
665
+
666
+ This modifies the input dictionary ``kwds``.
667
+
668
+ EXAMPLES::
669
+
670
+ sage: from sage.structure.indexed_generators import split_index_keywords
671
+ sage: d = {'string_quotes': False, 'bracket': None, 'base': QQ}
672
+ sage: split_index_keywords(d)
673
+ {'bracket': None, 'string_quotes': False}
674
+ sage: d
675
+ {'base': Rational Field}
676
+ """
677
+ ret = {}
678
+ for option in ['prefix', 'latex_prefix', 'bracket', 'latex_bracket',
679
+ 'scalar_mult', 'latex_scalar_mult', 'tensor_symbol',
680
+ 'sorting_key', 'sorting_reverse',
681
+ 'string_quotes']:
682
+ try:
683
+ ret[option] = kwds.pop(option)
684
+ except KeyError:
685
+ pass
686
+ return ret
687
+
688
+
689
+ def parse_indices_names(names, index_set, prefix, kwds=None):
690
+ """
691
+ Parse the names, index set, and prefix input, along with setting
692
+ default values for keyword arguments ``kwds``.
693
+
694
+ OUTPUT:
695
+
696
+ The triple ``(N, I, p)``:
697
+
698
+ - ``N`` is the tuple of variable names,
699
+ - ``I`` is the index set, and
700
+ - ``p`` is the prefix.
701
+
702
+ This modifies the dictionary ``kwds``.
703
+
704
+ .. NOTE::
705
+
706
+ When the indices, names, or prefix have not been given, it
707
+ should be passed to this function as ``None``.
708
+
709
+ .. NOTE::
710
+
711
+ For handling default prefixes, if the result will be ``None`` if
712
+ it is not processed in this function.
713
+
714
+ EXAMPLES::
715
+
716
+ sage: from sage.structure.indexed_generators import parse_indices_names
717
+ sage: d = {}
718
+ sage: parse_indices_names('x,y,z', ZZ, None, d)
719
+ (('x', 'y', 'z'), Integer Ring, None)
720
+ sage: d
721
+ {}
722
+ sage: d = {}
723
+ sage: parse_indices_names('x,y,z', None, None, d)
724
+ (('x', 'y', 'z'), {'x', 'y', 'z'}, '')
725
+ sage: d
726
+ {'string_quotes': False}
727
+ sage: d = {}
728
+ sage: parse_indices_names(None, ZZ, None, d)
729
+ (None, Integer Ring, None)
730
+ sage: d
731
+ {}
732
+
733
+ ::
734
+
735
+ sage: d = {'string_quotes':True, 'bracket':'['}
736
+ sage: parse_indices_names(['a','b','c'], ZZ, 'x', d)
737
+ (('a', 'b', 'c'), Integer Ring, 'x')
738
+ sage: d
739
+ {'bracket': '[', 'string_quotes': True}
740
+ sage: parse_indices_names('x,y,z', None, 'A', d)
741
+ (('x', 'y', 'z'), {'x', 'y', 'z'}, 'A')
742
+ sage: d
743
+ {'bracket': '[', 'string_quotes': True}
744
+ """
745
+ if index_set is None:
746
+ if names is None:
747
+ raise ValueError("either the indices or names must be given")
748
+
749
+ if prefix is None:
750
+ prefix = ''
751
+ if kwds is None:
752
+ kwds = {}
753
+ kwds.setdefault('string_quotes', False)
754
+
755
+ names, index_set = standardize_names_index_set(names, index_set, -1)
756
+
757
+ return (names, index_set, prefix)
758
+
759
+
760
+ def standardize_names_index_set(names=None, index_set=None, ngens=None):
761
+ """
762
+ Standardize the ``names`` and ``index_set`` inputs.
763
+
764
+ INPUT:
765
+
766
+ - ``names`` -- (optional) the variable names
767
+ - ``index_set`` -- (optional) the index set
768
+ - ``ngens`` -- (optional) the number of generators
769
+
770
+ If ``ngens`` is a negative number, then this does not check that
771
+ the number of variable names matches the size of the index set.
772
+
773
+ OUTPUT:
774
+
775
+ A pair ``(names_std, index_set_std)``, where ``names_std`` is either
776
+ ``None`` or a tuple of strings, and where ``index_set_std`` is a finite
777
+ enumerated set.
778
+ The purpose of ``index_set_std`` is to index the generators of some object
779
+ (e.g., the basis of a module); the strings in ``names_std``, when they
780
+ exist, are used for printing these indices. The ``ngens``
781
+
782
+ If ``names`` contains exactly one name ``X`` and ``ngens`` is greater than
783
+ 1, then ``names_std`` are ``Xi`` for ``i`` in ``range(ngens)``.
784
+
785
+ TESTS::
786
+
787
+ sage: from sage.structure.indexed_generators import standardize_names_index_set
788
+ sage: standardize_names_index_set('x,y')
789
+ (('x', 'y'), {'x', 'y'})
790
+ sage: standardize_names_index_set(['x','y'])
791
+ (('x', 'y'), {'x', 'y'})
792
+ sage: standardize_names_index_set(['x','y'], ['a','b'])
793
+ (('x', 'y'), {'a', 'b'})
794
+ sage: standardize_names_index_set('x,y', ngens=2)
795
+ (('x', 'y'), {'x', 'y'})
796
+ sage: standardize_names_index_set(index_set=['a','b'], ngens=2)
797
+ (None, {'a', 'b'})
798
+ sage: standardize_names_index_set('x', ngens=3)
799
+ (('x0', 'x1', 'x2'), {'x0', 'x1', 'x2'})
800
+
801
+ sage: standardize_names_index_set()
802
+ Traceback (most recent call last):
803
+ ...
804
+ ValueError: the index_set, names, or number of generators must be specified
805
+ sage: standardize_names_index_set(['x'], ['a', 'b'])
806
+ Traceback (most recent call last):
807
+ ...
808
+ IndexError: the number of names must equal the size of the indexing set
809
+ sage: standardize_names_index_set('x,y', ['a'])
810
+ Traceback (most recent call last):
811
+ ...
812
+ IndexError: the number of names must equal the size of the indexing set
813
+ sage: standardize_names_index_set('x,y,z', ngens=2)
814
+ Traceback (most recent call last):
815
+ ...
816
+ IndexError: the number of names must equal the number of generators
817
+ sage: standardize_names_index_set(index_set=['a'], ngens=2)
818
+ Traceback (most recent call last):
819
+ ...
820
+ IndexError: the size of the indexing set must equal the number of generators
821
+ """
822
+ if names is not None:
823
+ if ngens is None or ngens < 0:
824
+ names = normalize_names(-1, names)
825
+ else:
826
+ names = normalize_names(ngens, names)
827
+
828
+ if index_set is None:
829
+ if names is None:
830
+ # If neither is specified, we make range(ngens) the index set
831
+ if ngens is None:
832
+ raise ValueError("the index_set, names, or number of"
833
+ " generators must be specified")
834
+ index_set = tuple(range(ngens))
835
+ else:
836
+ # If only the names are specified, then we make the indexing set
837
+ # be the names
838
+ index_set = tuple(names)
839
+
840
+ from sage.sets.finite_enumerated_set import FiniteEnumeratedSet
841
+ if isinstance(index_set, dict): # dict of {name: index} -- not likely to be used
842
+ if names is not None:
843
+ raise ValueError("cannot give index_set as a dict and names")
844
+ names = normalize_names(-1, tuple(index_set.keys()))
845
+ index_set = FiniteEnumeratedSet([index_set[n] for n in names])
846
+ elif isinstance(index_set, str):
847
+ index_set = FiniteEnumeratedSet(list(index_set))
848
+ elif isinstance(index_set, (tuple, list)):
849
+ index_set = FiniteEnumeratedSet(index_set)
850
+
851
+ if ngens is None or ngens >= 0:
852
+ if names is not None:
853
+ if len(names) != index_set.cardinality():
854
+ raise IndexError("the number of names must equal"
855
+ " the size of the indexing set")
856
+ if ngens is not None and len(names) != ngens:
857
+ raise IndexError("the number of names must equal the"
858
+ " number of generators")
859
+ elif ngens is not None and index_set.cardinality() != ngens:
860
+ raise IndexError("the size of the indexing set must equal"
861
+ " the number of generators")
862
+
863
+ return (names, index_set)