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