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
sage/misc/misc_c.pyx ADDED
@@ -0,0 +1,766 @@
1
+ # sage_setup: distribution = sagemath-objects
2
+ """
3
+ Miscellaneous functions (Cython)
4
+
5
+ This file contains support for products, running totals, balanced
6
+ sums, and also a function to flush output from external library calls.
7
+
8
+ AUTHORS:
9
+
10
+ - William Stein (2005)
11
+ - Joel B. Mohler (2007-10-03): Reimplemented in Cython and optimized
12
+ - Robert Bradshaw (2007-10-26): Balanced product tree, other optimizations, (lazy) generator support
13
+ - Robert Bradshaw (2008-03-26): Balanced product tree for generators and iterators
14
+ - Stefan van Zwam (2013-06-06): Added bitset tests, some docstring cleanup
15
+ """
16
+
17
+ # ****************************************************************************
18
+ # Copyright (C) 2005 William Stein <wstein@gmail.com>
19
+ #
20
+ # This program is free software: you can redistribute it and/or modify
21
+ # it under the terms of the GNU General Public License as published by
22
+ # the Free Software Foundation, either version 2 of the License, or
23
+ # (at your option) any later version.
24
+ # https://www.gnu.org/licenses/
25
+ # ****************************************************************************
26
+ from copy import copy
27
+
28
+ from cpython.sequence cimport *
29
+ from cpython.list cimport *
30
+ from cpython.tuple cimport *
31
+ from cpython.number cimport *
32
+ from libc.stdio cimport fflush
33
+
34
+ cdef extern from *:
35
+ bint PyGen_Check(x)
36
+
37
+
38
+ def running_total(L, start=None):
39
+ """
40
+ Return a list where the `i`-th entry is the sum of all entries up to (and
41
+ including) `i`.
42
+
43
+ INPUT:
44
+
45
+ - ``L`` -- the list
46
+ - ``start`` -- (optional) a default start value
47
+
48
+ EXAMPLES::
49
+
50
+ sage: running_total(range(5))
51
+ [0, 1, 3, 6, 10]
52
+ sage: running_total("abcdef")
53
+ ['a', 'ab', 'abc', 'abcd', 'abcde', 'abcdef']
54
+ sage: running_total("abcdef", start="%")
55
+ ['%a', '%ab', '%abc', '%abcd', '%abcde', '%abcdef']
56
+ sage: running_total([1..10], start=100)
57
+ [101, 103, 106, 110, 115, 121, 128, 136, 145, 155]
58
+ sage: running_total([])
59
+ []
60
+ """
61
+ running = []
62
+ total = start
63
+ for x in L:
64
+ if total is None:
65
+ # This is the first entry
66
+ total = x
67
+ else:
68
+ total += x
69
+ PyList_Append(running, total)
70
+ return running
71
+
72
+
73
+ def prod(x, z=None, Py_ssize_t recursion_cutoff=5):
74
+ """
75
+ Return the product of the elements in the list x.
76
+
77
+ If optional argument z is not given, start the product with the first
78
+ element of the list, otherwise use z. The empty product is the int 1 if z
79
+ is not specified, and is z if given.
80
+
81
+ This assumes that your multiplication is associative; we do not promise
82
+ which end of the list we start at.
83
+
84
+ .. SEEALSO::
85
+
86
+ For the symbolic product function, see :func:`sage.calculus.calculus.symbolic_product`.
87
+
88
+ EXAMPLES::
89
+
90
+ sage: prod([1,2,34])
91
+ 68
92
+ sage: prod([2,3], 5)
93
+ 30
94
+ sage: prod((1,2,3), 5)
95
+ 30
96
+ sage: F = factor(-2006); F
97
+ -1 * 2 * 17 * 59
98
+ sage: prod(F)
99
+ -2006
100
+
101
+ AUTHORS:
102
+
103
+ - Joel B. Mohler (2007-10-03): Reimplemented in Cython and optimized
104
+ - Robert Bradshaw (2007-10-26): Balanced product tree, other optimizations, (lazy) generator support
105
+ - Robert Bradshaw (2008-03-26): Balanced product tree for generators and iterators
106
+ """
107
+ cdef Py_ssize_t n
108
+
109
+ if type(x) is not list and type(x) is not tuple:
110
+
111
+ if not PyGen_Check(x):
112
+
113
+ try:
114
+ return x.prod()
115
+ except AttributeError:
116
+ pass
117
+
118
+ try:
119
+ return x.mul()
120
+ except AttributeError:
121
+ pass
122
+
123
+ try:
124
+ n = len(x)
125
+ if n < 1000: # arbitrary limit
126
+ x = list(x)
127
+ except TypeError:
128
+ pass
129
+
130
+ if type(x) is not list:
131
+ try:
132
+ return iterator_prod(x, z)
133
+ except StopIteration:
134
+ x = []
135
+
136
+ n = len(x)
137
+
138
+ if n == 0:
139
+ if z is None:
140
+ import sage.rings.integer
141
+ return sage.rings.integer.Integer(1)
142
+ else:
143
+ return z
144
+
145
+ prod = balanced_list_prod(x, 0, n, recursion_cutoff)
146
+
147
+ if z is not None:
148
+ prod = z * prod
149
+
150
+ return prod
151
+
152
+
153
+ cdef balanced_list_prod(L, Py_ssize_t offset, Py_ssize_t count, Py_ssize_t cutoff):
154
+ """
155
+ INPUT:
156
+
157
+ - ``L`` -- the terms (MUST be a tuple or list)
158
+ - ``off`` -- offset in the list from which to start
159
+ - ``count`` -- how many terms in the product
160
+ - ``cutoff`` -- the minimum count to recurse on
161
+
162
+ OUTPUT:
163
+
164
+ ``L[offset] * L[offset+1] * ... * L[offset+count-1]``
165
+
166
+ .. NOTE::
167
+
168
+ The parameter cutoff must be at least 1, and there is no reason to
169
+ ever make it less than 3. However, there are at least two advantages
170
+ to setting it higher (and consequently not recursing all the way
171
+ down the tree). First, one avoids the overhead of the function
172
+ calls at the base of the tree (which is the majority of them) and
173
+ second, it allows one to save on object creation if inplace
174
+ operations are used. The asymptotic gains should usually be at the
175
+ top of the tree anyway.
176
+ """
177
+ cdef Py_ssize_t k
178
+ if count <= cutoff:
179
+ prod = <object>PySequence_Fast_GET_ITEM(L, offset)
180
+ for k from offset < k < offset + count:
181
+ prod *= <object>PySequence_Fast_GET_ITEM(L, k)
182
+ return prod
183
+ else:
184
+ k = (1 + count) >> 1
185
+ return balanced_list_prod(L, offset, k, cutoff) * balanced_list_prod(L, offset + k, count - k, cutoff)
186
+
187
+
188
+ cpdef iterator_prod(L, z=None, bint multiply=True):
189
+ """
190
+ Attempt to do a balanced product of an arbitrary and unknown length
191
+ sequence (such as a generator). Intermediate multiplications are always
192
+ done with subproducts of the same size (measured by the number of original
193
+ factors) up until the iterator terminates. This is optimal when and only
194
+ when there are exactly a power of two number of terms.
195
+
196
+ A StopIteration is raised if the iterator is empty and z is not given.
197
+
198
+ EXAMPLES::
199
+
200
+ sage: from sage.misc.misc_c import iterator_prod
201
+ sage: iterator_prod(1..5)
202
+ 120
203
+ sage: iterator_prod([], z='anything')
204
+ 'anything'
205
+
206
+ sage: from sage.misc.misc_c import NonAssociative
207
+ sage: L = [NonAssociative(label) for label in 'abcdef']
208
+ sage: iterator_prod(L)
209
+ (((a*b)*(c*d))*(e*f))
210
+
211
+ When ``multiply=False``, the items are added up instead (however this
212
+ interface should not be used directly, use :func:`balanced_sum` instead)::
213
+
214
+ sage: iterator_prod((1..5), multiply=False)
215
+ 15
216
+ """
217
+ cdef list sub_prods
218
+ L = iter(L)
219
+ if z is None:
220
+ sub_prods = [next(L)] * 10 # only take one element from L, the rest are just placeholders
221
+ # the list size can be dynamically increased later
222
+ else:
223
+ sub_prods = [z] * 10
224
+
225
+ cdef Py_ssize_t j
226
+ cdef Py_ssize_t i = 1
227
+ cdef Py_ssize_t tip = 0
228
+
229
+ for x in L:
230
+ i += 1
231
+ if i & 1:
232
+ # for odd i we extend the stack
233
+ tip += 1
234
+ if len(sub_prods) == tip:
235
+ sub_prods.append(x)
236
+ else:
237
+ sub_prods[tip] = x
238
+ continue
239
+ else:
240
+ # for even i we multiply the stack down
241
+ # by the number of factors of 2 in i
242
+ if multiply:
243
+ x = sub_prods[tip] * x
244
+ else:
245
+ x = sub_prods[tip] + x
246
+ for j from 1 <= j < 64:
247
+ if i & (1 << j):
248
+ break
249
+ tip -= 1
250
+ if multiply:
251
+ x = sub_prods[tip] * x
252
+ else:
253
+ x = sub_prods[tip] + x
254
+ sub_prods[tip] = x
255
+
256
+ while tip > 0:
257
+ tip -= 1
258
+ if multiply:
259
+ sub_prods[tip] *= sub_prods[tip + 1]
260
+ else:
261
+ sub_prods[tip] += sub_prods[tip + 1]
262
+
263
+ return sub_prods[0]
264
+
265
+
266
+ class NonAssociative:
267
+ """
268
+ This class is to test the balance nature of prod.
269
+
270
+ EXAMPLES::
271
+
272
+ sage: from sage.misc.misc_c import NonAssociative
273
+ sage: L = [NonAssociative(label) for label in 'abcdef']
274
+ sage: prod(L)
275
+ (((a*b)*c)*((d*e)*f))
276
+ sage: L = [NonAssociative(label) for label in range(20)]
277
+ sage: prod(L, recursion_cutoff=5)
278
+ ((((((0*1)*2)*3)*4)*((((5*6)*7)*8)*9))*(((((10*11)*12)*13)*14)*((((15*16)*17)*18)*19)))
279
+ sage: prod(L, recursion_cutoff=1)
280
+ (((((0*1)*2)*(3*4))*(((5*6)*7)*(8*9)))*((((10*11)*12)*(13*14))*(((15*16)*17)*(18*19))))
281
+ sage: L = [NonAssociative(label) for label in range(14)]
282
+ sage: prod(L, recursion_cutoff=1)
283
+ ((((0*1)*(2*3))*((4*5)*6))*(((7*8)*(9*10))*((11*12)*13)))
284
+ """
285
+ def __init__(self, left, right=None):
286
+ """
287
+ EXAMPLES::
288
+
289
+ sage: from sage.misc.misc_c import NonAssociative
290
+ sage: NonAssociative('a')
291
+ a
292
+ sage: NonAssociative('a','b')
293
+ (a*b)
294
+ """
295
+ self.left = left
296
+ self.right = right
297
+
298
+ def __repr__(self):
299
+ """
300
+ EXAMPLES::
301
+
302
+ sage: from sage.misc.misc_c import NonAssociative
303
+ sage: NonAssociative(1)
304
+ 1
305
+ sage: NonAssociative(2,3)
306
+ (2*3)
307
+ """
308
+ if self.right is None:
309
+ return str(self.left)
310
+ else:
311
+ return "(%s*%s)" % (self.left, self.right)
312
+
313
+ def __mul__(self, other):
314
+ """
315
+ EXAMPLES::
316
+
317
+ sage: from sage.misc.misc_c import NonAssociative
318
+ sage: a, b, c = [NonAssociative(label) for label in 'abc']
319
+ sage: (a*b)*c
320
+ ((a*b)*c)
321
+ sage: a*(b*c)
322
+ (a*(b*c))
323
+ """
324
+ return NonAssociative(self, other)
325
+
326
+
327
+ def balanced_sum(x, z=None, Py_ssize_t recursion_cutoff=5):
328
+ """
329
+ Return the sum of the elements in the list x. If optional
330
+ argument z is not given, start the sum with the first element of
331
+ the list, otherwise use z. The empty product is the int 0 if z is
332
+ not specified, and is z if given. The sum is computed
333
+ recursively, where the sum is split up if the list is greater than
334
+ recursion_cutoff. recursion_cutoff must be at least 3.
335
+
336
+ This assumes that your addition is associative; we do not promise
337
+ which end of the list we start at.
338
+
339
+ EXAMPLES::
340
+
341
+ sage: balanced_sum([1,2,34])
342
+ 37
343
+ sage: balanced_sum([2,3], 5)
344
+ 10
345
+ sage: balanced_sum((1,2,3), 5)
346
+ 11
347
+
348
+ Order should be preserved::
349
+
350
+ sage: balanced_sum([[i] for i in range(10)], [], recursion_cutoff=3)
351
+ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
352
+
353
+ We make copies when appropriate so that we do not accidentally
354
+ modify the arguments::
355
+
356
+ sage: list(range(10^5))==balanced_sum([[i] for i in range(10^5)], [])
357
+ True
358
+ sage: list(range(10^5))==balanced_sum([[i] for i in range(10^5)], [])
359
+ True
360
+
361
+ TESTS::
362
+
363
+ sage: balanced_sum((1..3)) # nonempty, z=None
364
+ 6
365
+ sage: balanced_sum((1..-1)) # empty, z=None
366
+ 0
367
+ sage: balanced_sum((1..3), 5) # nonempty, z is not None
368
+ 11
369
+ sage: balanced_sum((1..-1), 5) # empty, z is not None
370
+ 5
371
+ sage: balanced_sum([1])
372
+ 1
373
+
374
+ AUTHORS:
375
+
376
+ - Joel B. Mohler (2007-10-03): Reimplemented in Cython and optimized
377
+ - Robert Bradshaw (2007-10-26): Balanced product tree, other optimizations, (lazy) generator support
378
+ """
379
+ if recursion_cutoff < 3:
380
+ raise ValueError("recursion_cutoff must be at least 3")
381
+
382
+ if type(x) is not list and type(x) is not tuple:
383
+
384
+ if PyGen_Check(x):
385
+ return iterator_prod(x, z, multiply=False)
386
+ else:
387
+ try:
388
+ return x.sum()
389
+ except AttributeError:
390
+ pass
391
+
392
+ x = list(x)
393
+
394
+ cdef Py_ssize_t n = len(x)
395
+
396
+ if n == 0:
397
+ if z is None:
398
+ import sage.rings.integer
399
+ return sage.rings.integer.Integer(0)
400
+ else:
401
+ return z
402
+
403
+ sum = balanced_list_sum(x, 0, n, recursion_cutoff)
404
+
405
+ if z is not None:
406
+ sum = z + sum
407
+
408
+ return sum
409
+
410
+
411
+ cdef balanced_list_sum(L, Py_ssize_t offset, Py_ssize_t count, Py_ssize_t cutoff):
412
+ """
413
+ INPUT:
414
+
415
+ - ``L`` -- the terms (MUST be a tuple or list)
416
+ - ``off`` -- offset in the list from which to start
417
+ - ``count`` -- how many terms in the sum; must be positive
418
+ - ``cutoff`` -- the minimum count to recurse on; must be at least 2
419
+
420
+ OUTPUT:
421
+
422
+ ``L[offset] + L[offset+1] + ... + L[offset+count-1]``
423
+
424
+ .. NOTE::
425
+
426
+ The parameter cutoff must be at least 3. However, there are
427
+ at least two advantages to setting it higher (and
428
+ consequently not recursing all the way down the
429
+ tree). First, one avoids the overhead of the function calls
430
+ at the base of the tree (which is the majority of them) and
431
+ second, it allows one to save on object creation if inplace
432
+ operations are used. The asymptotic gains should usually be
433
+ at the top of the tree anyway.
434
+ """
435
+ cdef Py_ssize_t k
436
+ if count <= cutoff:
437
+ sum = <object>PySequence_Fast_GET_ITEM(L, offset)
438
+ for k in range(offset + 1, offset + count):
439
+ sum += <object>PySequence_Fast_GET_ITEM(L, k)
440
+ return sum
441
+ else:
442
+ k = (1 + count) >> 1
443
+ return balanced_list_sum(L, offset, k, cutoff) + balanced_list_sum(L, offset + k, count - k, cutoff)
444
+
445
+
446
+ cpdef list normalize_index(object key, int size):
447
+ """
448
+ Normalize an index key and return a valid index or list of indices
449
+ within the range(0, size).
450
+
451
+ INPUT:
452
+
453
+ - ``key`` -- the index key, which can be either an integer, a tuple/list of
454
+ integers, or a slice
455
+ - ``size`` -- the size of the collection
456
+
457
+ OUTPUT:
458
+
459
+ A tuple (SINGLE, VALUE), where SINGLE is True (i.e., 1) if VALUE
460
+ is an integer and False (i.e., 0) if VALUE is a list.
461
+
462
+ EXAMPLES::
463
+
464
+ sage: from sage.misc.misc_c import normalize_index
465
+ sage: normalize_index(-6,5)
466
+ Traceback (most recent call last):
467
+ ...
468
+ IndexError: index out of range
469
+ sage: normalize_index(-5,5)
470
+ [0]
471
+ sage: normalize_index(-4,5)
472
+ [1]
473
+ sage: normalize_index(-3,5)
474
+ [2]
475
+ sage: normalize_index(-2,5)
476
+ [3]
477
+ sage: normalize_index(-1,5)
478
+ [4]
479
+ sage: normalize_index(0,5)
480
+ [0]
481
+ sage: normalize_index(1,5)
482
+ [1]
483
+ sage: normalize_index(2,5)
484
+ [2]
485
+ sage: normalize_index(3,5)
486
+ [3]
487
+ sage: normalize_index(4,5)
488
+ [4]
489
+ sage: normalize_index(5,5)
490
+ Traceback (most recent call last):
491
+ ...
492
+ IndexError: index out of range
493
+ sage: normalize_index(6,5)
494
+ Traceback (most recent call last):
495
+ ...
496
+ IndexError: index out of range
497
+ sage: normalize_index((4,-6),5)
498
+ Traceback (most recent call last):
499
+ ...
500
+ IndexError: index out of range
501
+ sage: normalize_index((-2,3),5)
502
+ [3, 3]
503
+ sage: normalize_index((5,0),5)
504
+ Traceback (most recent call last):
505
+ ...
506
+ IndexError: index out of range
507
+ sage: normalize_index((-5,2),5)
508
+ [0, 2]
509
+ sage: normalize_index((0,-2),5)
510
+ [0, 3]
511
+ sage: normalize_index((2,-3),5)
512
+ [2, 2]
513
+ sage: normalize_index((3,3),5)
514
+ [3, 3]
515
+ sage: normalize_index((-2,-5),5)
516
+ [3, 0]
517
+ sage: normalize_index((-2,-4),5)
518
+ [3, 1]
519
+ sage: normalize_index([-2,-1,3],5)
520
+ [3, 4, 3]
521
+ sage: normalize_index([4,2,1],5)
522
+ [4, 2, 1]
523
+ sage: normalize_index([-2,-3,-4],5)
524
+ [3, 2, 1]
525
+ sage: normalize_index([3,-2,-3],5)
526
+ [3, 3, 2]
527
+ sage: normalize_index([-5,2,-3],5)
528
+ [0, 2, 2]
529
+ sage: normalize_index([4,4,-5],5)
530
+ [4, 4, 0]
531
+ sage: s=slice(None,None,None); normalize_index(s,5)==list(range(5))[s]
532
+ True
533
+ sage: s=slice(None,None,-2); normalize_index(s,5)==list(range(5))[s]
534
+ True
535
+ sage: s=slice(None,None,4); normalize_index(s,5)==list(range(5))[s]
536
+ True
537
+ sage: s=slice(None,-2,None); normalize_index(s,5)==list(range(5))[s]
538
+ True
539
+ sage: s=slice(None,-2,-2); normalize_index(s,5)==list(range(5))[s]
540
+ True
541
+ sage: s=slice(None,-2,4); normalize_index(s,5)==list(range(5))[s]
542
+ True
543
+ sage: s=slice(None,4,None); normalize_index(s,5)==list(range(5))[s]
544
+ True
545
+ sage: s=slice(None,4,-2); normalize_index(s,5)==list(range(5))[s]
546
+ True
547
+ sage: s=slice(None,4,4); normalize_index(s,5)==list(range(5))[s]
548
+ True
549
+ sage: s=slice(-2,None,None); normalize_index(s,5)==list(range(5))[s]
550
+ True
551
+ sage: s=slice(-2,None,-2); normalize_index(s,5)==list(range(5))[s]
552
+ True
553
+ sage: s=slice(-2,None,4); normalize_index(s,5)==list(range(5))[s]
554
+ True
555
+ sage: s=slice(-2,-2,None); normalize_index(s,5)==list(range(5))[s]
556
+ True
557
+ sage: s=slice(-2,-2,-2); normalize_index(s,5)==list(range(5))[s]
558
+ True
559
+ sage: s=slice(-2,-2,4); normalize_index(s,5)==list(range(5))[s]
560
+ True
561
+ sage: s=slice(-2,4,None); normalize_index(s,5)==list(range(5))[s]
562
+ True
563
+ sage: s=slice(-2,4,-2); normalize_index(s,5)==list(range(5))[s]
564
+ True
565
+ sage: s=slice(-2,4,4); normalize_index(s,5)==list(range(5))[s]
566
+ True
567
+ sage: s=slice(4,None,None); normalize_index(s,5)==list(range(5))[s]
568
+ True
569
+ sage: s=slice(4,None,-2); normalize_index(s,5)==list(range(5))[s]
570
+ True
571
+ sage: s=slice(4,None,4); normalize_index(s,5)==list(range(5))[s]
572
+ True
573
+ sage: s=slice(4,-2,None); normalize_index(s,5)==list(range(5))[s]
574
+ True
575
+ sage: s=slice(4,-2,-2); normalize_index(s,5)==list(range(5))[s]
576
+ True
577
+ sage: s=slice(4,-2,4); normalize_index(s,5)==list(range(5))[s]
578
+ True
579
+ sage: s=slice(4,4,None); normalize_index(s,5)==list(range(5))[s]
580
+ True
581
+ sage: s=slice(4,4,-2); normalize_index(s,5)==list(range(5))[s]
582
+ True
583
+ sage: s=slice(4,4,4); normalize_index(s,5)==list(range(5))[s]
584
+ True
585
+ """
586
+ cdef tuple index_tuple
587
+ cdef list return_list = []
588
+ cdef Py_ssize_t index
589
+ cdef Py_ssize_t i
590
+ cdef object index_obj
591
+
592
+ if PyIndex_Check(key):
593
+ index = key
594
+ if index < 0:
595
+ index += size
596
+ if index < 0 or index >= size:
597
+ raise IndexError("index out of range")
598
+ return [index]
599
+ elif isinstance(key, slice):
600
+ return list(range(*key.indices(size)))
601
+ elif type(key) is tuple:
602
+ index_tuple = key
603
+ elif type(key) is list:
604
+ index_tuple = PyList_AsTuple(key)
605
+ elif type(key) is range:
606
+ index_tuple = tuple(key)
607
+ else:
608
+ raise TypeError("index must be an integer or slice or a tuple/list of integers and slices")
609
+
610
+ # Cython does not automatically use PyTuple_GET_SIZE, even though
611
+ # it knows that index_tuple is tuple
612
+ for i in range(PyTuple_GET_SIZE(index_tuple)):
613
+ index_obj = index_tuple[i]
614
+ if PyIndex_Check(index_obj):
615
+ index = index_obj
616
+ if index < 0:
617
+ index += size
618
+ if index < 0 or index >= size:
619
+ raise IndexError("index out of range")
620
+ return_list.append(index)
621
+ elif isinstance(index_obj, slice):
622
+ return_list.extend(range(*index_obj.indices(size)))
623
+ else:
624
+ raise TypeError("index must be an integer or slice")
625
+ return return_list
626
+
627
+
628
+ cdef class sized_iter:
629
+ """
630
+ Wrapper for an iterator to verify that it has a specified length.
631
+
632
+ INPUT:
633
+
634
+ - ``iterable`` -- object to be iterated over
635
+
636
+ - ``length`` -- (optional) the required length; if this is not
637
+ given, then ``len(iterable)`` will be used
638
+
639
+ If the iterable does not have the given length, a :exc:`ValueError` is
640
+ raised during iteration.
641
+
642
+ EXAMPLES::
643
+
644
+ sage: from sage.misc.misc_c import sized_iter
645
+ sage: list(sized_iter(range(4)))
646
+ [0, 1, 2, 3]
647
+ sage: list(sized_iter(range(4), 4))
648
+ [0, 1, 2, 3]
649
+ sage: list(sized_iter(range(5), 4))
650
+ Traceback (most recent call last):
651
+ ...
652
+ ValueError: sequence too long (expected length 4, got more)
653
+ sage: list(sized_iter(range(3), 4))
654
+ Traceback (most recent call last):
655
+ ...
656
+ ValueError: sequence too short (expected length 4, got 3)
657
+
658
+ If the iterable is too long, we get the error on the last entry::
659
+
660
+ sage: it = sized_iter(range(5), 2)
661
+ sage: next(it)
662
+ 0
663
+ sage: next(it)
664
+ Traceback (most recent call last):
665
+ ...
666
+ ValueError: sequence too long (expected length 2, got more)
667
+
668
+ When the expected length is zero, the iterator is checked on
669
+ construction::
670
+
671
+ sage: list(sized_iter([], 0))
672
+ []
673
+ sage: sized_iter([1], 0)
674
+ Traceback (most recent call last):
675
+ ...
676
+ ValueError: sequence too long (expected length 0, got more)
677
+
678
+ If no ``length`` is given, the iterable must implement ``__len__``::
679
+
680
+ sage: sized_iter(x for x in range(4))
681
+ Traceback (most recent call last):
682
+ ...
683
+ TypeError: object of type 'generator' has no len()
684
+ """
685
+ cdef iterator
686
+ cdef Py_ssize_t index, size
687
+
688
+ def __init__(self, iterable, length=None):
689
+ self.iterator = iter(iterable)
690
+ self.index = 0
691
+ if length is None:
692
+ self.size = len(iterable)
693
+ else:
694
+ self.size = length
695
+ self.check()
696
+
697
+ def __iter__(self):
698
+ return self
699
+
700
+ def __len__(self):
701
+ """
702
+ Number of entries remaining, assuming that the expected length
703
+ is the actual length.
704
+
705
+ EXAMPLES::
706
+
707
+ sage: from sage.misc.misc_c import sized_iter
708
+ sage: it = sized_iter(range(4), 4)
709
+ sage: len(it)
710
+ 4
711
+ sage: next(it)
712
+ 0
713
+ sage: len(it)
714
+ 3
715
+ """
716
+ return self.size - self.index
717
+
718
+ cdef inline int check(self) except -1:
719
+ """
720
+ If the iterator is supposed to be exhausted, check that it is.
721
+ """
722
+ if self.index < self.size:
723
+ return 0
724
+ try:
725
+ next(self.iterator)
726
+ except StopIteration:
727
+ pass
728
+ else:
729
+ raise ValueError(f"sequence too long (expected length {self.size}, got more)")
730
+
731
+ def __next__(self):
732
+ if self.index >= self.size:
733
+ raise StopIteration
734
+ try:
735
+ x = next(self.iterator)
736
+ except StopIteration:
737
+ raise ValueError(f"sequence too short (expected length {self.size}, got {self.index})")
738
+ self.index += 1
739
+ self.check()
740
+ return x
741
+
742
+
743
+ def cyflush():
744
+ """
745
+ Flush any output left over from external library calls.
746
+
747
+ Starting with Python 3, some output from external libraries (like
748
+ FLINT) is not flushed, and so if a doctest produces such output,
749
+ the output may not appear until a later doctest. See
750
+ :issue:`28649`.
751
+
752
+ Use this function after a doctest which produces potentially
753
+ unflushed output to force it to be flushed.
754
+
755
+ EXAMPLES::
756
+
757
+ sage: R.<t> = QQ[]
758
+ sage: t^(sys.maxsize//2) # needs sage.libs.flint
759
+ Traceback (most recent call last):
760
+ ...
761
+ RuntimeError: FLINT exception
762
+ sage: from sage.misc.misc_c import cyflush
763
+ sage: cyflush()
764
+ ...
765
+ """
766
+ fflush(NULL)