passagemath-categories 10.6.32__cp314-cp314t-musllinux_1_2_aarch64.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 (719) hide show
  1. passagemath_categories-10.6.32.dist-info/METADATA +156 -0
  2. passagemath_categories-10.6.32.dist-info/RECORD +719 -0
  3. passagemath_categories-10.6.32.dist-info/WHEEL +5 -0
  4. passagemath_categories-10.6.32.dist-info/top_level.txt +2 -0
  5. passagemath_categories.libs/libgcc_s-2d945d6c.so.1 +0 -0
  6. passagemath_categories.libs/libgmp-28992bcb.so.10.5.0 +0 -0
  7. passagemath_categories.libs/libstdc++-85f2cd6d.so.6.0.33 +0 -0
  8. sage/all__sagemath_categories.py +28 -0
  9. sage/arith/all.py +38 -0
  10. sage/arith/constants.pxd +27 -0
  11. sage/arith/functions.cpython-314t-aarch64-linux-musl.so +0 -0
  12. sage/arith/functions.pxd +4 -0
  13. sage/arith/functions.pyx +221 -0
  14. sage/arith/misc.py +6552 -0
  15. sage/arith/multi_modular.cpython-314t-aarch64-linux-musl.so +0 -0
  16. sage/arith/multi_modular.pxd +39 -0
  17. sage/arith/multi_modular.pyx +994 -0
  18. sage/arith/rational_reconstruction.cpython-314t-aarch64-linux-musl.so +0 -0
  19. sage/arith/rational_reconstruction.pxd +4 -0
  20. sage/arith/rational_reconstruction.pyx +115 -0
  21. sage/arith/srange.cpython-314t-aarch64-linux-musl.so +0 -0
  22. sage/arith/srange.pyx +571 -0
  23. sage/calculus/all__sagemath_categories.py +2 -0
  24. sage/calculus/functional.py +481 -0
  25. sage/calculus/functions.py +151 -0
  26. sage/categories/additive_groups.py +73 -0
  27. sage/categories/additive_magmas.py +1044 -0
  28. sage/categories/additive_monoids.py +114 -0
  29. sage/categories/additive_semigroups.py +184 -0
  30. sage/categories/affine_weyl_groups.py +238 -0
  31. sage/categories/algebra_ideals.py +95 -0
  32. sage/categories/algebra_modules.py +96 -0
  33. sage/categories/algebras.py +349 -0
  34. sage/categories/algebras_with_basis.py +377 -0
  35. sage/categories/all.py +160 -0
  36. sage/categories/aperiodic_semigroups.py +29 -0
  37. sage/categories/associative_algebras.py +47 -0
  38. sage/categories/bialgebras.py +101 -0
  39. sage/categories/bialgebras_with_basis.py +414 -0
  40. sage/categories/bimodules.py +206 -0
  41. sage/categories/chain_complexes.py +268 -0
  42. sage/categories/classical_crystals.py +480 -0
  43. sage/categories/coalgebras.py +405 -0
  44. sage/categories/coalgebras_with_basis.py +232 -0
  45. sage/categories/coercion_methods.cpython-314t-aarch64-linux-musl.so +0 -0
  46. sage/categories/coercion_methods.pyx +52 -0
  47. sage/categories/commutative_additive_groups.py +104 -0
  48. sage/categories/commutative_additive_monoids.py +45 -0
  49. sage/categories/commutative_additive_semigroups.py +48 -0
  50. sage/categories/commutative_algebra_ideals.py +87 -0
  51. sage/categories/commutative_algebras.py +94 -0
  52. sage/categories/commutative_ring_ideals.py +58 -0
  53. sage/categories/commutative_rings.py +736 -0
  54. sage/categories/complete_discrete_valuation.py +293 -0
  55. sage/categories/complex_reflection_groups.py +145 -0
  56. sage/categories/complex_reflection_or_generalized_coxeter_groups.py +1249 -0
  57. sage/categories/coxeter_group_algebras.py +186 -0
  58. sage/categories/coxeter_groups.py +3402 -0
  59. sage/categories/crystals.py +2628 -0
  60. sage/categories/cw_complexes.py +216 -0
  61. sage/categories/dedekind_domains.py +137 -0
  62. sage/categories/discrete_valuation.py +325 -0
  63. sage/categories/distributive_magmas_and_additive_magmas.py +100 -0
  64. sage/categories/division_rings.py +114 -0
  65. sage/categories/domains.py +95 -0
  66. sage/categories/drinfeld_modules.py +789 -0
  67. sage/categories/dual.py +42 -0
  68. sage/categories/enumerated_sets.py +1146 -0
  69. sage/categories/euclidean_domains.py +271 -0
  70. sage/categories/examples/algebras_with_basis.py +102 -0
  71. sage/categories/examples/all.py +1 -0
  72. sage/categories/examples/commutative_additive_monoids.py +130 -0
  73. sage/categories/examples/commutative_additive_semigroups.py +199 -0
  74. sage/categories/examples/coxeter_groups.py +8 -0
  75. sage/categories/examples/crystals.py +236 -0
  76. sage/categories/examples/cw_complexes.py +163 -0
  77. sage/categories/examples/facade_sets.py +187 -0
  78. sage/categories/examples/filtered_algebras_with_basis.py +204 -0
  79. sage/categories/examples/filtered_modules_with_basis.py +154 -0
  80. sage/categories/examples/finite_coxeter_groups.py +252 -0
  81. sage/categories/examples/finite_dimensional_algebras_with_basis.py +148 -0
  82. sage/categories/examples/finite_dimensional_lie_algebras_with_basis.py +495 -0
  83. sage/categories/examples/finite_enumerated_sets.py +208 -0
  84. sage/categories/examples/finite_monoids.py +150 -0
  85. sage/categories/examples/finite_semigroups.py +190 -0
  86. sage/categories/examples/finite_weyl_groups.py +191 -0
  87. sage/categories/examples/graded_connected_hopf_algebras_with_basis.py +152 -0
  88. sage/categories/examples/graded_modules_with_basis.py +168 -0
  89. sage/categories/examples/graphs.py +122 -0
  90. sage/categories/examples/hopf_algebras_with_basis.py +145 -0
  91. sage/categories/examples/infinite_enumerated_sets.py +190 -0
  92. sage/categories/examples/lie_algebras.py +352 -0
  93. sage/categories/examples/lie_algebras_with_basis.py +196 -0
  94. sage/categories/examples/magmas.py +162 -0
  95. sage/categories/examples/manifolds.py +94 -0
  96. sage/categories/examples/monoids.py +144 -0
  97. sage/categories/examples/posets.py +178 -0
  98. sage/categories/examples/semigroups.py +580 -0
  99. sage/categories/examples/semigroups_cython.cpython-314t-aarch64-linux-musl.so +0 -0
  100. sage/categories/examples/semigroups_cython.pyx +221 -0
  101. sage/categories/examples/semirings.py +249 -0
  102. sage/categories/examples/sets_cat.py +706 -0
  103. sage/categories/examples/sets_with_grading.py +101 -0
  104. sage/categories/examples/with_realizations.py +542 -0
  105. sage/categories/fields.py +991 -0
  106. sage/categories/filtered_algebras.py +63 -0
  107. sage/categories/filtered_algebras_with_basis.py +548 -0
  108. sage/categories/filtered_hopf_algebras_with_basis.py +138 -0
  109. sage/categories/filtered_modules.py +210 -0
  110. sage/categories/filtered_modules_with_basis.py +1209 -0
  111. sage/categories/finite_complex_reflection_groups.py +1506 -0
  112. sage/categories/finite_coxeter_groups.py +1138 -0
  113. sage/categories/finite_crystals.py +103 -0
  114. sage/categories/finite_dimensional_algebras_with_basis.py +1860 -0
  115. sage/categories/finite_dimensional_bialgebras_with_basis.py +33 -0
  116. sage/categories/finite_dimensional_coalgebras_with_basis.py +33 -0
  117. sage/categories/finite_dimensional_graded_lie_algebras_with_basis.py +231 -0
  118. sage/categories/finite_dimensional_hopf_algebras_with_basis.py +38 -0
  119. sage/categories/finite_dimensional_lie_algebras_with_basis.py +2774 -0
  120. sage/categories/finite_dimensional_modules_with_basis.py +1407 -0
  121. sage/categories/finite_dimensional_nilpotent_lie_algebras_with_basis.py +167 -0
  122. sage/categories/finite_dimensional_semisimple_algebras_with_basis.py +270 -0
  123. sage/categories/finite_enumerated_sets.py +769 -0
  124. sage/categories/finite_fields.py +252 -0
  125. sage/categories/finite_groups.py +256 -0
  126. sage/categories/finite_lattice_posets.py +242 -0
  127. sage/categories/finite_monoids.py +316 -0
  128. sage/categories/finite_permutation_groups.py +339 -0
  129. sage/categories/finite_posets.py +1994 -0
  130. sage/categories/finite_semigroups.py +136 -0
  131. sage/categories/finite_sets.py +93 -0
  132. sage/categories/finite_weyl_groups.py +39 -0
  133. sage/categories/finitely_generated_lambda_bracket_algebras.py +112 -0
  134. sage/categories/finitely_generated_lie_conformal_algebras.py +114 -0
  135. sage/categories/finitely_generated_magmas.py +57 -0
  136. sage/categories/finitely_generated_semigroups.py +214 -0
  137. sage/categories/function_fields.py +76 -0
  138. sage/categories/g_sets.py +77 -0
  139. sage/categories/gcd_domains.py +65 -0
  140. sage/categories/generalized_coxeter_groups.py +94 -0
  141. sage/categories/graded_algebras.py +85 -0
  142. sage/categories/graded_algebras_with_basis.py +258 -0
  143. sage/categories/graded_bialgebras.py +32 -0
  144. sage/categories/graded_bialgebras_with_basis.py +32 -0
  145. sage/categories/graded_coalgebras.py +65 -0
  146. sage/categories/graded_coalgebras_with_basis.py +51 -0
  147. sage/categories/graded_hopf_algebras.py +41 -0
  148. sage/categories/graded_hopf_algebras_with_basis.py +169 -0
  149. sage/categories/graded_lie_algebras.py +91 -0
  150. sage/categories/graded_lie_algebras_with_basis.py +44 -0
  151. sage/categories/graded_lie_conformal_algebras.py +74 -0
  152. sage/categories/graded_modules.py +133 -0
  153. sage/categories/graded_modules_with_basis.py +329 -0
  154. sage/categories/graphs.py +138 -0
  155. sage/categories/group_algebras.py +430 -0
  156. sage/categories/groupoid.py +94 -0
  157. sage/categories/groups.py +667 -0
  158. sage/categories/h_trivial_semigroups.py +64 -0
  159. sage/categories/hecke_modules.py +185 -0
  160. sage/categories/highest_weight_crystals.py +980 -0
  161. sage/categories/hopf_algebras.py +219 -0
  162. sage/categories/hopf_algebras_with_basis.py +309 -0
  163. sage/categories/infinite_enumerated_sets.py +115 -0
  164. sage/categories/integral_domains.py +203 -0
  165. sage/categories/j_trivial_semigroups.py +29 -0
  166. sage/categories/kac_moody_algebras.py +82 -0
  167. sage/categories/kahler_algebras.py +203 -0
  168. sage/categories/l_trivial_semigroups.py +63 -0
  169. sage/categories/lambda_bracket_algebras.py +280 -0
  170. sage/categories/lambda_bracket_algebras_with_basis.py +107 -0
  171. sage/categories/lattice_posets.py +89 -0
  172. sage/categories/left_modules.py +49 -0
  173. sage/categories/lie_algebras.py +1070 -0
  174. sage/categories/lie_algebras_with_basis.py +261 -0
  175. sage/categories/lie_conformal_algebras.py +350 -0
  176. sage/categories/lie_conformal_algebras_with_basis.py +147 -0
  177. sage/categories/lie_groups.py +73 -0
  178. sage/categories/loop_crystals.py +1290 -0
  179. sage/categories/magmas.py +1189 -0
  180. sage/categories/magmas_and_additive_magmas.py +149 -0
  181. sage/categories/magmatic_algebras.py +365 -0
  182. sage/categories/manifolds.py +352 -0
  183. sage/categories/matrix_algebras.py +40 -0
  184. sage/categories/metric_spaces.py +387 -0
  185. sage/categories/modular_abelian_varieties.py +78 -0
  186. sage/categories/modules.py +989 -0
  187. sage/categories/modules_with_basis.py +2794 -0
  188. sage/categories/monoid_algebras.py +38 -0
  189. sage/categories/monoids.py +739 -0
  190. sage/categories/noetherian_rings.py +87 -0
  191. sage/categories/number_fields.py +242 -0
  192. sage/categories/ore_modules.py +189 -0
  193. sage/categories/partially_ordered_monoids.py +49 -0
  194. sage/categories/permutation_groups.py +63 -0
  195. sage/categories/pointed_sets.py +42 -0
  196. sage/categories/polyhedra.py +74 -0
  197. sage/categories/poor_man_map.py +270 -0
  198. sage/categories/posets.py +722 -0
  199. sage/categories/principal_ideal_domains.py +270 -0
  200. sage/categories/quantum_group_representations.py +543 -0
  201. sage/categories/quotient_fields.py +728 -0
  202. sage/categories/r_trivial_semigroups.py +45 -0
  203. sage/categories/regular_crystals.py +898 -0
  204. sage/categories/regular_supercrystals.py +170 -0
  205. sage/categories/right_modules.py +49 -0
  206. sage/categories/ring_ideals.py +74 -0
  207. sage/categories/rings.py +1904 -0
  208. sage/categories/rngs.py +175 -0
  209. sage/categories/schemes.py +393 -0
  210. sage/categories/semigroups.py +1060 -0
  211. sage/categories/semirings.py +71 -0
  212. sage/categories/semisimple_algebras.py +114 -0
  213. sage/categories/sets_with_grading.py +235 -0
  214. sage/categories/shephard_groups.py +43 -0
  215. sage/categories/signed_tensor.py +120 -0
  216. sage/categories/simplicial_complexes.py +134 -0
  217. sage/categories/simplicial_sets.py +1206 -0
  218. sage/categories/super_algebras.py +149 -0
  219. sage/categories/super_algebras_with_basis.py +144 -0
  220. sage/categories/super_hopf_algebras_with_basis.py +126 -0
  221. sage/categories/super_lie_conformal_algebras.py +193 -0
  222. sage/categories/super_modules.py +229 -0
  223. sage/categories/super_modules_with_basis.py +193 -0
  224. sage/categories/supercommutative_algebras.py +99 -0
  225. sage/categories/supercrystals.py +406 -0
  226. sage/categories/tensor.py +110 -0
  227. sage/categories/topological_spaces.py +170 -0
  228. sage/categories/triangular_kac_moody_algebras.py +439 -0
  229. sage/categories/tutorial.py +58 -0
  230. sage/categories/unique_factorization_domains.py +318 -0
  231. sage/categories/unital_algebras.py +426 -0
  232. sage/categories/vector_bundles.py +159 -0
  233. sage/categories/vector_spaces.py +357 -0
  234. sage/categories/weyl_groups.py +853 -0
  235. sage/combinat/all__sagemath_categories.py +34 -0
  236. sage/combinat/backtrack.py +180 -0
  237. sage/combinat/combinat.py +2269 -0
  238. sage/combinat/combinat_cython.cpython-314t-aarch64-linux-musl.so +0 -0
  239. sage/combinat/combinat_cython.pxd +6 -0
  240. sage/combinat/combinat_cython.pyx +390 -0
  241. sage/combinat/combination.py +796 -0
  242. sage/combinat/combinatorial_map.py +416 -0
  243. sage/combinat/composition.py +2192 -0
  244. sage/combinat/dlx.py +510 -0
  245. sage/combinat/integer_lists/__init__.py +7 -0
  246. sage/combinat/integer_lists/base.cpython-314t-aarch64-linux-musl.so +0 -0
  247. sage/combinat/integer_lists/base.pxd +16 -0
  248. sage/combinat/integer_lists/base.pyx +713 -0
  249. sage/combinat/integer_lists/invlex.cpython-314t-aarch64-linux-musl.so +0 -0
  250. sage/combinat/integer_lists/invlex.pxd +4 -0
  251. sage/combinat/integer_lists/invlex.pyx +1650 -0
  252. sage/combinat/integer_lists/lists.py +328 -0
  253. sage/combinat/integer_lists/nn.py +48 -0
  254. sage/combinat/integer_vector.py +1818 -0
  255. sage/combinat/integer_vector_weighted.py +413 -0
  256. sage/combinat/matrices/all__sagemath_categories.py +5 -0
  257. sage/combinat/matrices/dancing_links.cpython-314t-aarch64-linux-musl.so +0 -0
  258. sage/combinat/matrices/dancing_links.pyx +1159 -0
  259. sage/combinat/matrices/dancing_links_c.h +380 -0
  260. sage/combinat/matrices/dlxcpp.py +136 -0
  261. sage/combinat/partition.py +10070 -0
  262. sage/combinat/partitions.cpython-314t-aarch64-linux-musl.so +0 -0
  263. sage/combinat/partitions.pyx +743 -0
  264. sage/combinat/permutation.py +10168 -0
  265. sage/combinat/permutation_cython.cpython-314t-aarch64-linux-musl.so +0 -0
  266. sage/combinat/permutation_cython.pxd +11 -0
  267. sage/combinat/permutation_cython.pyx +407 -0
  268. sage/combinat/q_analogues.py +1090 -0
  269. sage/combinat/ranker.py +268 -0
  270. sage/combinat/subset.py +1561 -0
  271. sage/combinat/subsets_hereditary.py +202 -0
  272. sage/combinat/subsets_pairwise.py +184 -0
  273. sage/combinat/tools.py +63 -0
  274. sage/combinat/tuple.py +348 -0
  275. sage/data_structures/all.py +2 -0
  276. sage/data_structures/all__sagemath_categories.py +2 -0
  277. sage/data_structures/binary_matrix.pxd +138 -0
  278. sage/data_structures/binary_search.cpython-314t-aarch64-linux-musl.so +0 -0
  279. sage/data_structures/binary_search.pxd +3 -0
  280. sage/data_structures/binary_search.pyx +66 -0
  281. sage/data_structures/bitset.cpython-314t-aarch64-linux-musl.so +0 -0
  282. sage/data_structures/bitset.pxd +40 -0
  283. sage/data_structures/bitset.pyx +2385 -0
  284. sage/data_structures/bitset_base.cpython-314t-aarch64-linux-musl.so +0 -0
  285. sage/data_structures/bitset_base.pxd +926 -0
  286. sage/data_structures/bitset_base.pyx +117 -0
  287. sage/data_structures/bitset_intrinsics.h +487 -0
  288. sage/data_structures/blas_dict.cpython-314t-aarch64-linux-musl.so +0 -0
  289. sage/data_structures/blas_dict.pxd +12 -0
  290. sage/data_structures/blas_dict.pyx +469 -0
  291. sage/data_structures/list_of_pairs.cpython-314t-aarch64-linux-musl.so +0 -0
  292. sage/data_structures/list_of_pairs.pxd +16 -0
  293. sage/data_structures/list_of_pairs.pyx +122 -0
  294. sage/data_structures/mutable_poset.py +3312 -0
  295. sage/data_structures/pairing_heap.cpython-314t-aarch64-linux-musl.so +0 -0
  296. sage/data_structures/pairing_heap.h +346 -0
  297. sage/data_structures/pairing_heap.pxd +88 -0
  298. sage/data_structures/pairing_heap.pyx +1464 -0
  299. sage/data_structures/sparse_bitset.pxd +62 -0
  300. sage/data_structures/stream.py +5070 -0
  301. sage/databases/all__sagemath_categories.py +7 -0
  302. sage/databases/sql_db.py +2236 -0
  303. sage/ext/all__sagemath_categories.py +3 -0
  304. sage/ext/fast_callable.cpython-314t-aarch64-linux-musl.so +0 -0
  305. sage/ext/fast_callable.pxd +4 -0
  306. sage/ext/fast_callable.pyx +2746 -0
  307. sage/ext/fast_eval.cpython-314t-aarch64-linux-musl.so +0 -0
  308. sage/ext/fast_eval.pxd +1 -0
  309. sage/ext/fast_eval.pyx +102 -0
  310. sage/ext/interpreters/__init__.py +1 -0
  311. sage/ext/interpreters/all__sagemath_categories.py +2 -0
  312. sage/ext/interpreters/wrapper_el.cpython-314t-aarch64-linux-musl.so +0 -0
  313. sage/ext/interpreters/wrapper_el.pxd +18 -0
  314. sage/ext/interpreters/wrapper_el.pyx +148 -0
  315. sage/ext/interpreters/wrapper_py.cpython-314t-aarch64-linux-musl.so +0 -0
  316. sage/ext/interpreters/wrapper_py.pxd +17 -0
  317. sage/ext/interpreters/wrapper_py.pyx +133 -0
  318. sage/functions/airy.py +937 -0
  319. sage/functions/all.py +97 -0
  320. sage/functions/bessel.py +2102 -0
  321. sage/functions/error.py +784 -0
  322. sage/functions/exp_integral.py +1529 -0
  323. sage/functions/gamma.py +1087 -0
  324. sage/functions/generalized.py +672 -0
  325. sage/functions/hyperbolic.py +747 -0
  326. sage/functions/hypergeometric.py +1156 -0
  327. sage/functions/jacobi.py +1705 -0
  328. sage/functions/log.py +1402 -0
  329. sage/functions/min_max.py +338 -0
  330. sage/functions/orthogonal_polys.py +3106 -0
  331. sage/functions/other.py +2303 -0
  332. sage/functions/piecewise.py +1505 -0
  333. sage/functions/prime_pi.cpython-314t-aarch64-linux-musl.so +0 -0
  334. sage/functions/prime_pi.pyx +262 -0
  335. sage/functions/special.py +1212 -0
  336. sage/functions/spike_function.py +278 -0
  337. sage/functions/transcendental.py +690 -0
  338. sage/functions/trig.py +1062 -0
  339. sage/functions/wigner.py +726 -0
  340. sage/geometry/abc.cpython-314t-aarch64-linux-musl.so +0 -0
  341. sage/geometry/abc.pyx +82 -0
  342. sage/geometry/all__sagemath_categories.py +1 -0
  343. sage/groups/all__sagemath_categories.py +11 -0
  344. sage/groups/generic.py +1733 -0
  345. sage/groups/groups_catalog.py +113 -0
  346. sage/groups/perm_gps/all__sagemath_categories.py +1 -0
  347. sage/groups/perm_gps/partn_ref/all.py +1 -0
  348. sage/groups/perm_gps/partn_ref/all__sagemath_categories.py +1 -0
  349. sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.cpython-314t-aarch64-linux-musl.so +0 -0
  350. sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pxd +52 -0
  351. sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx +906 -0
  352. sage/groups/perm_gps/partn_ref/canonical_augmentation.cpython-314t-aarch64-linux-musl.so +0 -0
  353. sage/groups/perm_gps/partn_ref/canonical_augmentation.pxd +85 -0
  354. sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx +534 -0
  355. sage/groups/perm_gps/partn_ref/data_structures.cpython-314t-aarch64-linux-musl.so +0 -0
  356. sage/groups/perm_gps/partn_ref/data_structures.pxd +576 -0
  357. sage/groups/perm_gps/partn_ref/data_structures.pyx +1792 -0
  358. sage/groups/perm_gps/partn_ref/double_coset.cpython-314t-aarch64-linux-musl.so +0 -0
  359. sage/groups/perm_gps/partn_ref/double_coset.pxd +45 -0
  360. sage/groups/perm_gps/partn_ref/double_coset.pyx +739 -0
  361. sage/groups/perm_gps/partn_ref/refinement_lists.cpython-314t-aarch64-linux-musl.so +0 -0
  362. sage/groups/perm_gps/partn_ref/refinement_lists.pxd +18 -0
  363. sage/groups/perm_gps/partn_ref/refinement_lists.pyx +82 -0
  364. sage/groups/perm_gps/partn_ref/refinement_python.cpython-314t-aarch64-linux-musl.so +0 -0
  365. sage/groups/perm_gps/partn_ref/refinement_python.pxd +16 -0
  366. sage/groups/perm_gps/partn_ref/refinement_python.pyx +564 -0
  367. sage/groups/perm_gps/partn_ref/refinement_sets.cpython-314t-aarch64-linux-musl.so +0 -0
  368. sage/groups/perm_gps/partn_ref/refinement_sets.pxd +60 -0
  369. sage/groups/perm_gps/partn_ref/refinement_sets.pyx +858 -0
  370. sage/interfaces/abc.py +140 -0
  371. sage/interfaces/all.py +58 -0
  372. sage/interfaces/all__sagemath_categories.py +1 -0
  373. sage/interfaces/expect.py +1643 -0
  374. sage/interfaces/interface.py +1682 -0
  375. sage/interfaces/process.cpython-314t-aarch64-linux-musl.so +0 -0
  376. sage/interfaces/process.pxd +5 -0
  377. sage/interfaces/process.pyx +288 -0
  378. sage/interfaces/quit.py +167 -0
  379. sage/interfaces/sage0.py +604 -0
  380. sage/interfaces/sagespawn.cpython-314t-aarch64-linux-musl.so +0 -0
  381. sage/interfaces/sagespawn.pyx +308 -0
  382. sage/interfaces/tab_completion.py +101 -0
  383. sage/misc/all__sagemath_categories.py +78 -0
  384. sage/misc/allocator.cpython-314t-aarch64-linux-musl.so +0 -0
  385. sage/misc/allocator.pxd +6 -0
  386. sage/misc/allocator.pyx +47 -0
  387. sage/misc/binary_tree.cpython-314t-aarch64-linux-musl.so +0 -0
  388. sage/misc/binary_tree.pxd +29 -0
  389. sage/misc/binary_tree.pyx +537 -0
  390. sage/misc/callable_dict.cpython-314t-aarch64-linux-musl.so +0 -0
  391. sage/misc/callable_dict.pyx +89 -0
  392. sage/misc/citation.cpython-314t-aarch64-linux-musl.so +0 -0
  393. sage/misc/citation.pyx +159 -0
  394. sage/misc/converting_dict.py +293 -0
  395. sage/misc/defaults.py +129 -0
  396. sage/misc/derivative.cpython-314t-aarch64-linux-musl.so +0 -0
  397. sage/misc/derivative.pyx +223 -0
  398. sage/misc/functional.py +2005 -0
  399. sage/misc/html.py +589 -0
  400. sage/misc/latex.py +2673 -0
  401. sage/misc/latex_macros.py +236 -0
  402. sage/misc/latex_standalone.py +1833 -0
  403. sage/misc/map_threaded.py +38 -0
  404. sage/misc/mathml.py +76 -0
  405. sage/misc/method_decorator.py +88 -0
  406. sage/misc/mrange.py +755 -0
  407. sage/misc/multireplace.py +41 -0
  408. sage/misc/object_multiplexer.py +92 -0
  409. sage/misc/parser.cpython-314t-aarch64-linux-musl.so +0 -0
  410. sage/misc/parser.pyx +1107 -0
  411. sage/misc/random_testing.py +264 -0
  412. sage/misc/rest_index_of_methods.py +377 -0
  413. sage/misc/search.cpython-314t-aarch64-linux-musl.so +0 -0
  414. sage/misc/search.pxd +2 -0
  415. sage/misc/search.pyx +68 -0
  416. sage/misc/stopgap.cpython-314t-aarch64-linux-musl.so +0 -0
  417. sage/misc/stopgap.pyx +95 -0
  418. sage/misc/table.py +853 -0
  419. sage/monoids/all__sagemath_categories.py +1 -0
  420. sage/monoids/indexed_free_monoid.py +1071 -0
  421. sage/monoids/monoid.py +82 -0
  422. sage/numerical/all__sagemath_categories.py +1 -0
  423. sage/numerical/backends/all__sagemath_categories.py +1 -0
  424. sage/numerical/backends/generic_backend.cpython-314t-aarch64-linux-musl.so +0 -0
  425. sage/numerical/backends/generic_backend.pxd +61 -0
  426. sage/numerical/backends/generic_backend.pyx +1893 -0
  427. sage/numerical/backends/generic_sdp_backend.cpython-314t-aarch64-linux-musl.so +0 -0
  428. sage/numerical/backends/generic_sdp_backend.pxd +38 -0
  429. sage/numerical/backends/generic_sdp_backend.pyx +755 -0
  430. sage/parallel/all.py +6 -0
  431. sage/parallel/decorate.py +575 -0
  432. sage/parallel/map_reduce.py +1997 -0
  433. sage/parallel/multiprocessing_sage.py +76 -0
  434. sage/parallel/ncpus.py +35 -0
  435. sage/parallel/parallelism.py +364 -0
  436. sage/parallel/reference.py +47 -0
  437. sage/parallel/use_fork.py +333 -0
  438. sage/rings/abc.cpython-314t-aarch64-linux-musl.so +0 -0
  439. sage/rings/abc.pxd +31 -0
  440. sage/rings/abc.pyx +526 -0
  441. sage/rings/algebraic_closure_finite_field.py +1154 -0
  442. sage/rings/all__sagemath_categories.py +91 -0
  443. sage/rings/big_oh.py +227 -0
  444. sage/rings/continued_fraction.py +2754 -0
  445. sage/rings/continued_fraction_gosper.py +220 -0
  446. sage/rings/factorint.cpython-314t-aarch64-linux-musl.so +0 -0
  447. sage/rings/factorint.pyx +295 -0
  448. sage/rings/fast_arith.cpython-314t-aarch64-linux-musl.so +0 -0
  449. sage/rings/fast_arith.pxd +21 -0
  450. sage/rings/fast_arith.pyx +535 -0
  451. sage/rings/finite_rings/all__sagemath_categories.py +9 -0
  452. sage/rings/finite_rings/conway_polynomials.py +542 -0
  453. sage/rings/finite_rings/element_base.cpython-314t-aarch64-linux-musl.so +0 -0
  454. sage/rings/finite_rings/element_base.pxd +12 -0
  455. sage/rings/finite_rings/element_base.pyx +1176 -0
  456. sage/rings/finite_rings/finite_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
  457. sage/rings/finite_rings/finite_field_base.pxd +7 -0
  458. sage/rings/finite_rings/finite_field_base.pyx +2171 -0
  459. sage/rings/finite_rings/finite_field_constructor.py +827 -0
  460. sage/rings/finite_rings/finite_field_prime_modn.py +372 -0
  461. sage/rings/finite_rings/galois_group.py +154 -0
  462. sage/rings/finite_rings/hom_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
  463. sage/rings/finite_rings/hom_finite_field.pxd +23 -0
  464. sage/rings/finite_rings/hom_finite_field.pyx +856 -0
  465. sage/rings/finite_rings/hom_prime_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
  466. sage/rings/finite_rings/hom_prime_finite_field.pxd +15 -0
  467. sage/rings/finite_rings/hom_prime_finite_field.pyx +164 -0
  468. sage/rings/finite_rings/homset.py +357 -0
  469. sage/rings/finite_rings/integer_mod.cpython-314t-aarch64-linux-musl.so +0 -0
  470. sage/rings/finite_rings/integer_mod.pxd +56 -0
  471. sage/rings/finite_rings/integer_mod.pyx +4586 -0
  472. sage/rings/finite_rings/integer_mod_limits.h +11 -0
  473. sage/rings/finite_rings/integer_mod_ring.py +2044 -0
  474. sage/rings/finite_rings/residue_field.cpython-314t-aarch64-linux-musl.so +0 -0
  475. sage/rings/finite_rings/residue_field.pxd +30 -0
  476. sage/rings/finite_rings/residue_field.pyx +1811 -0
  477. sage/rings/finite_rings/stdint.pxd +19 -0
  478. sage/rings/fraction_field.py +1452 -0
  479. sage/rings/fraction_field_element.cpython-314t-aarch64-linux-musl.so +0 -0
  480. sage/rings/fraction_field_element.pyx +1357 -0
  481. sage/rings/function_field/all.py +7 -0
  482. sage/rings/function_field/all__sagemath_categories.py +2 -0
  483. sage/rings/function_field/constructor.py +218 -0
  484. sage/rings/function_field/element.cpython-314t-aarch64-linux-musl.so +0 -0
  485. sage/rings/function_field/element.pxd +11 -0
  486. sage/rings/function_field/element.pyx +1008 -0
  487. sage/rings/function_field/element_rational.cpython-314t-aarch64-linux-musl.so +0 -0
  488. sage/rings/function_field/element_rational.pyx +513 -0
  489. sage/rings/function_field/extensions.py +230 -0
  490. sage/rings/function_field/function_field.py +1468 -0
  491. sage/rings/function_field/function_field_rational.py +1005 -0
  492. sage/rings/function_field/ideal.py +1155 -0
  493. sage/rings/function_field/ideal_rational.py +629 -0
  494. sage/rings/function_field/jacobian_base.py +826 -0
  495. sage/rings/function_field/jacobian_hess.py +1053 -0
  496. sage/rings/function_field/jacobian_khuri_makdisi.py +1027 -0
  497. sage/rings/function_field/maps.py +1039 -0
  498. sage/rings/function_field/order.py +281 -0
  499. sage/rings/function_field/order_basis.py +586 -0
  500. sage/rings/function_field/order_rational.py +576 -0
  501. sage/rings/function_field/place.py +426 -0
  502. sage/rings/function_field/place_rational.py +181 -0
  503. sage/rings/generic.py +320 -0
  504. sage/rings/homset.py +332 -0
  505. sage/rings/ideal.py +1885 -0
  506. sage/rings/ideal_monoid.py +215 -0
  507. sage/rings/infinity.py +1890 -0
  508. sage/rings/integer.cpython-314t-aarch64-linux-musl.so +0 -0
  509. sage/rings/integer.pxd +45 -0
  510. sage/rings/integer.pyx +7874 -0
  511. sage/rings/integer_ring.cpython-314t-aarch64-linux-musl.so +0 -0
  512. sage/rings/integer_ring.pxd +8 -0
  513. sage/rings/integer_ring.pyx +1693 -0
  514. sage/rings/laurent_series_ring.py +931 -0
  515. sage/rings/laurent_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
  516. sage/rings/laurent_series_ring_element.pxd +11 -0
  517. sage/rings/laurent_series_ring_element.pyx +1927 -0
  518. sage/rings/lazy_series.py +7815 -0
  519. sage/rings/lazy_series_ring.py +4356 -0
  520. sage/rings/localization.py +1043 -0
  521. sage/rings/morphism.cpython-314t-aarch64-linux-musl.so +0 -0
  522. sage/rings/morphism.pxd +39 -0
  523. sage/rings/morphism.pyx +3299 -0
  524. sage/rings/multi_power_series_ring.py +1145 -0
  525. sage/rings/multi_power_series_ring_element.py +2184 -0
  526. sage/rings/noncommutative_ideals.cpython-314t-aarch64-linux-musl.so +0 -0
  527. sage/rings/noncommutative_ideals.pyx +423 -0
  528. sage/rings/number_field/all__sagemath_categories.py +1 -0
  529. sage/rings/number_field/number_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
  530. sage/rings/number_field/number_field_base.pxd +8 -0
  531. sage/rings/number_field/number_field_base.pyx +507 -0
  532. sage/rings/number_field/number_field_element_base.cpython-314t-aarch64-linux-musl.so +0 -0
  533. sage/rings/number_field/number_field_element_base.pxd +6 -0
  534. sage/rings/number_field/number_field_element_base.pyx +36 -0
  535. sage/rings/number_field/number_field_ideal.py +3550 -0
  536. sage/rings/padics/all__sagemath_categories.py +4 -0
  537. sage/rings/padics/local_generic.py +1670 -0
  538. sage/rings/padics/local_generic_element.cpython-314t-aarch64-linux-musl.so +0 -0
  539. sage/rings/padics/local_generic_element.pxd +5 -0
  540. sage/rings/padics/local_generic_element.pyx +1017 -0
  541. sage/rings/padics/misc.py +256 -0
  542. sage/rings/padics/padic_generic.py +1911 -0
  543. sage/rings/padics/pow_computer.cpython-314t-aarch64-linux-musl.so +0 -0
  544. sage/rings/padics/pow_computer.pxd +38 -0
  545. sage/rings/padics/pow_computer.pyx +671 -0
  546. sage/rings/padics/precision_error.py +24 -0
  547. sage/rings/polynomial/all__sagemath_categories.py +25 -0
  548. sage/rings/polynomial/commutative_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
  549. sage/rings/polynomial/commutative_polynomial.pxd +6 -0
  550. sage/rings/polynomial/commutative_polynomial.pyx +24 -0
  551. sage/rings/polynomial/cyclotomic.cpython-314t-aarch64-linux-musl.so +0 -0
  552. sage/rings/polynomial/cyclotomic.pyx +404 -0
  553. sage/rings/polynomial/flatten.py +711 -0
  554. sage/rings/polynomial/ideal.py +102 -0
  555. sage/rings/polynomial/infinite_polynomial_element.py +1768 -0
  556. sage/rings/polynomial/infinite_polynomial_ring.py +1653 -0
  557. sage/rings/polynomial/laurent_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
  558. sage/rings/polynomial/laurent_polynomial.pxd +18 -0
  559. sage/rings/polynomial/laurent_polynomial.pyx +2190 -0
  560. sage/rings/polynomial/laurent_polynomial_ideal.py +590 -0
  561. sage/rings/polynomial/laurent_polynomial_ring.py +832 -0
  562. sage/rings/polynomial/laurent_polynomial_ring_base.py +708 -0
  563. sage/rings/polynomial/multi_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
  564. sage/rings/polynomial/multi_polynomial.pxd +12 -0
  565. sage/rings/polynomial/multi_polynomial.pyx +3082 -0
  566. sage/rings/polynomial/multi_polynomial_element.py +2570 -0
  567. sage/rings/polynomial/multi_polynomial_ideal.py +5771 -0
  568. sage/rings/polynomial/multi_polynomial_ring.py +947 -0
  569. sage/rings/polynomial/multi_polynomial_ring_base.cpython-314t-aarch64-linux-musl.so +0 -0
  570. sage/rings/polynomial/multi_polynomial_ring_base.pxd +15 -0
  571. sage/rings/polynomial/multi_polynomial_ring_base.pyx +1855 -0
  572. sage/rings/polynomial/multi_polynomial_sequence.py +2204 -0
  573. sage/rings/polynomial/polydict.cpython-314t-aarch64-linux-musl.so +0 -0
  574. sage/rings/polynomial/polydict.pxd +45 -0
  575. sage/rings/polynomial/polydict.pyx +2701 -0
  576. sage/rings/polynomial/polynomial_compiled.cpython-314t-aarch64-linux-musl.so +0 -0
  577. sage/rings/polynomial/polynomial_compiled.pxd +59 -0
  578. sage/rings/polynomial/polynomial_compiled.pyx +509 -0
  579. sage/rings/polynomial/polynomial_element.cpython-314t-aarch64-linux-musl.so +0 -0
  580. sage/rings/polynomial/polynomial_element.pxd +64 -0
  581. sage/rings/polynomial/polynomial_element.pyx +13255 -0
  582. sage/rings/polynomial/polynomial_element_generic.py +1637 -0
  583. sage/rings/polynomial/polynomial_fateman.py +97 -0
  584. sage/rings/polynomial/polynomial_quotient_ring.py +2465 -0
  585. sage/rings/polynomial/polynomial_quotient_ring_element.py +779 -0
  586. sage/rings/polynomial/polynomial_ring.py +3784 -0
  587. sage/rings/polynomial/polynomial_ring_constructor.py +1051 -0
  588. sage/rings/polynomial/polynomial_ring_homomorphism.cpython-314t-aarch64-linux-musl.so +0 -0
  589. sage/rings/polynomial/polynomial_ring_homomorphism.pxd +5 -0
  590. sage/rings/polynomial/polynomial_ring_homomorphism.pyx +121 -0
  591. sage/rings/polynomial/polynomial_singular_interface.py +549 -0
  592. sage/rings/polynomial/symmetric_ideal.py +989 -0
  593. sage/rings/polynomial/symmetric_reduction.cpython-314t-aarch64-linux-musl.so +0 -0
  594. sage/rings/polynomial/symmetric_reduction.pxd +8 -0
  595. sage/rings/polynomial/symmetric_reduction.pyx +669 -0
  596. sage/rings/polynomial/term_order.py +2279 -0
  597. sage/rings/polynomial/toy_buchberger.py +449 -0
  598. sage/rings/polynomial/toy_d_basis.py +387 -0
  599. sage/rings/polynomial/toy_variety.py +362 -0
  600. sage/rings/power_series_mpoly.cpython-314t-aarch64-linux-musl.so +0 -0
  601. sage/rings/power_series_mpoly.pxd +9 -0
  602. sage/rings/power_series_mpoly.pyx +161 -0
  603. sage/rings/power_series_poly.cpython-314t-aarch64-linux-musl.so +0 -0
  604. sage/rings/power_series_poly.pxd +10 -0
  605. sage/rings/power_series_poly.pyx +1317 -0
  606. sage/rings/power_series_ring.py +1441 -0
  607. sage/rings/power_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
  608. sage/rings/power_series_ring_element.pxd +12 -0
  609. sage/rings/power_series_ring_element.pyx +3028 -0
  610. sage/rings/puiseux_series_ring.py +487 -0
  611. sage/rings/puiseux_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
  612. sage/rings/puiseux_series_ring_element.pxd +7 -0
  613. sage/rings/puiseux_series_ring_element.pyx +1055 -0
  614. sage/rings/qqbar_decorators.py +167 -0
  615. sage/rings/quotient_ring.py +1598 -0
  616. sage/rings/quotient_ring_element.py +979 -0
  617. sage/rings/rational.cpython-314t-aarch64-linux-musl.so +0 -0
  618. sage/rings/rational.pxd +20 -0
  619. sage/rings/rational.pyx +4284 -0
  620. sage/rings/rational_field.py +1730 -0
  621. sage/rings/real_double.cpython-314t-aarch64-linux-musl.so +0 -0
  622. sage/rings/real_double.pxd +16 -0
  623. sage/rings/real_double.pyx +2218 -0
  624. sage/rings/real_lazy.cpython-314t-aarch64-linux-musl.so +0 -0
  625. sage/rings/real_lazy.pxd +30 -0
  626. sage/rings/real_lazy.pyx +1773 -0
  627. sage/rings/ring.cpython-314t-aarch64-linux-musl.so +0 -0
  628. sage/rings/ring.pxd +30 -0
  629. sage/rings/ring.pyx +850 -0
  630. sage/rings/semirings/all.py +3 -0
  631. sage/rings/semirings/non_negative_integer_semiring.py +107 -0
  632. sage/rings/semirings/tropical_mpolynomial.py +972 -0
  633. sage/rings/semirings/tropical_polynomial.py +997 -0
  634. sage/rings/semirings/tropical_semiring.cpython-314t-aarch64-linux-musl.so +0 -0
  635. sage/rings/semirings/tropical_semiring.pyx +676 -0
  636. sage/rings/semirings/tropical_variety.py +1701 -0
  637. sage/rings/sum_of_squares.cpython-314t-aarch64-linux-musl.so +0 -0
  638. sage/rings/sum_of_squares.pxd +3 -0
  639. sage/rings/sum_of_squares.pyx +336 -0
  640. sage/rings/tests.py +504 -0
  641. sage/schemes/affine/affine_homset.py +508 -0
  642. sage/schemes/affine/affine_morphism.py +1574 -0
  643. sage/schemes/affine/affine_point.py +460 -0
  644. sage/schemes/affine/affine_rational_point.py +308 -0
  645. sage/schemes/affine/affine_space.py +1264 -0
  646. sage/schemes/affine/affine_subscheme.py +592 -0
  647. sage/schemes/affine/all.py +25 -0
  648. sage/schemes/all__sagemath_categories.py +5 -0
  649. sage/schemes/generic/algebraic_scheme.py +2092 -0
  650. sage/schemes/generic/all.py +5 -0
  651. sage/schemes/generic/ambient_space.py +400 -0
  652. sage/schemes/generic/divisor.py +465 -0
  653. sage/schemes/generic/divisor_group.py +313 -0
  654. sage/schemes/generic/glue.py +84 -0
  655. sage/schemes/generic/homset.py +820 -0
  656. sage/schemes/generic/hypersurface.py +234 -0
  657. sage/schemes/generic/morphism.py +2107 -0
  658. sage/schemes/generic/point.py +237 -0
  659. sage/schemes/generic/scheme.py +1190 -0
  660. sage/schemes/generic/spec.py +199 -0
  661. sage/schemes/product_projective/all.py +6 -0
  662. sage/schemes/product_projective/homset.py +236 -0
  663. sage/schemes/product_projective/morphism.py +517 -0
  664. sage/schemes/product_projective/point.py +568 -0
  665. sage/schemes/product_projective/rational_point.py +550 -0
  666. sage/schemes/product_projective/space.py +1301 -0
  667. sage/schemes/product_projective/subscheme.py +466 -0
  668. sage/schemes/projective/all.py +24 -0
  669. sage/schemes/projective/proj_bdd_height.py +453 -0
  670. sage/schemes/projective/projective_homset.py +718 -0
  671. sage/schemes/projective/projective_morphism.py +2792 -0
  672. sage/schemes/projective/projective_point.py +1484 -0
  673. sage/schemes/projective/projective_rational_point.py +569 -0
  674. sage/schemes/projective/projective_space.py +2571 -0
  675. sage/schemes/projective/projective_subscheme.py +1574 -0
  676. sage/sets/all.py +17 -0
  677. sage/sets/cartesian_product.py +376 -0
  678. sage/sets/condition_set.py +525 -0
  679. sage/sets/disjoint_set.cpython-314t-aarch64-linux-musl.so +0 -0
  680. sage/sets/disjoint_set.pxd +36 -0
  681. sage/sets/disjoint_set.pyx +998 -0
  682. sage/sets/disjoint_union_enumerated_sets.py +625 -0
  683. sage/sets/family.cpython-314t-aarch64-linux-musl.so +0 -0
  684. sage/sets/family.pxd +12 -0
  685. sage/sets/family.pyx +1556 -0
  686. sage/sets/finite_enumerated_set.py +406 -0
  687. sage/sets/finite_set_map_cy.cpython-314t-aarch64-linux-musl.so +0 -0
  688. sage/sets/finite_set_map_cy.pxd +34 -0
  689. sage/sets/finite_set_map_cy.pyx +708 -0
  690. sage/sets/finite_set_maps.py +591 -0
  691. sage/sets/image_set.py +448 -0
  692. sage/sets/integer_range.py +829 -0
  693. sage/sets/non_negative_integers.py +241 -0
  694. sage/sets/positive_integers.py +93 -0
  695. sage/sets/primes.py +188 -0
  696. sage/sets/real_set.py +2760 -0
  697. sage/sets/recursively_enumerated_set.cpython-314t-aarch64-linux-musl.so +0 -0
  698. sage/sets/recursively_enumerated_set.pxd +31 -0
  699. sage/sets/recursively_enumerated_set.pyx +2082 -0
  700. sage/sets/set.py +2083 -0
  701. sage/sets/set_from_iterator.py +1021 -0
  702. sage/sets/totally_ordered_finite_set.py +329 -0
  703. sage/symbolic/all__sagemath_categories.py +1 -0
  704. sage/symbolic/function.cpython-314t-aarch64-linux-musl.so +0 -0
  705. sage/symbolic/function.pxd +29 -0
  706. sage/symbolic/function.pyx +1488 -0
  707. sage/symbolic/symbols.py +56 -0
  708. sage/tests/all__sagemath_categories.py +1 -0
  709. sage/tests/cython.cpython-314t-aarch64-linux-musl.so +0 -0
  710. sage/tests/cython.pyx +37 -0
  711. sage/tests/stl_vector.cpython-314t-aarch64-linux-musl.so +0 -0
  712. sage/tests/stl_vector.pyx +171 -0
  713. sage/typeset/all.py +6 -0
  714. sage/typeset/ascii_art.py +295 -0
  715. sage/typeset/character_art.py +789 -0
  716. sage/typeset/character_art_factory.py +572 -0
  717. sage/typeset/symbols.py +334 -0
  718. sage/typeset/unicode_art.py +183 -0
  719. sage/typeset/unicode_characters.py +101 -0
@@ -0,0 +1,4356 @@
1
+ # sage_setup: distribution = sagemath-categories
2
+ r"""
3
+ Lazy Series Rings
4
+
5
+ We provide lazy implementations for various `\NN`-graded rings.
6
+
7
+ .. csv-table::
8
+ :class: contentstable
9
+ :widths: 30, 70
10
+ :delim: |
11
+
12
+ :class:`LazyLaurentSeriesRing` | The ring of lazy Laurent series.
13
+ :class:`LazyPowerSeriesRing` | The ring of (possibly multivariate) lazy Taylor series.
14
+ :class:`LazyCompletionGradedAlgebra` | The completion of a graded algebra consisting of formal series.
15
+ :class:`LazySymmetricFunctions` | The ring of (possibly multivariate) lazy symmetric functions.
16
+ :class:`LazyDirichletSeriesRing` | The ring of lazy Dirichlet series.
17
+
18
+ .. SEEALSO::
19
+
20
+ :class:`sage.rings.padics.generic_nodes.pAdicRelaxedGeneric`,
21
+ :func:`sage.rings.padics.factory.ZpER`
22
+
23
+ .. WARNING::
24
+
25
+ When the halting precision is infinite, the default for ``bool(f)``
26
+ is ``True`` for any lazy series ``f`` that is not known to be zero.
27
+ This could end up resulting in infinite loops::
28
+
29
+ sage: L.<x> = LazyPowerSeriesRing(ZZ)
30
+ sage: f = L(lambda n: 0, valuation=0)
31
+ sage: 1 / f # not tested - infinite loop
32
+
33
+ .. SEEALSO::
34
+
35
+ The examples of :class:`LazyLaurentSeriesRing` contain a discussion
36
+ about the different methods of comparisons the lazy series can use.
37
+
38
+ AUTHORS:
39
+
40
+ - Kwankyu Lee (2019-02-24): initial version
41
+ - Tejasvi Chebrolu, Martin Rubey, Travis Scrimshaw (2021-08):
42
+ refactored and expanded functionality
43
+ """
44
+
45
+ # ****************************************************************************
46
+ # Copyright (C) 2019 Kwankyu Lee <ekwankyu@gmail.com>
47
+ # 2022 Martin Rubey <martin.rubey at tuwien.ac.at>
48
+ # 2022 Travis Scrimshaw <tcscrims at gmail.com>
49
+ #
50
+ # This program is free software: you can redistribute it and/or modify
51
+ # it under the terms of the GNU General Public License as published by
52
+ # the Free Software Foundation, either version 2 of the License, or
53
+ # (at your option) any later version.
54
+ # https://www.gnu.org/licenses/
55
+ # ****************************************************************************
56
+
57
+ from sage.structure.unique_representation import UniqueRepresentation
58
+ from sage.structure.parent import Parent
59
+ from sage.structure.element import parent
60
+
61
+ from sage.categories.algebras import Algebras
62
+ from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis
63
+ from sage.categories.rings import Rings
64
+ from sage.categories.unique_factorization_domains import UniqueFactorizationDomains
65
+ from sage.categories.integral_domains import IntegralDomains
66
+ from sage.categories.fields import Fields
67
+ from sage.categories.complete_discrete_valuation import (CompleteDiscreteValuationFields,
68
+ CompleteDiscreteValuationRings)
69
+
70
+ from sage.misc.cachefunc import cached_method
71
+ from sage.misc.lazy_attribute import lazy_attribute
72
+
73
+ from sage.rings.integer_ring import ZZ
74
+ from sage.rings.infinity import infinity
75
+ from sage.rings.polynomial.laurent_polynomial_ring import LaurentPolynomialRing
76
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
77
+ from sage.rings.lazy_series import (LazyModuleElement,
78
+ LazyLaurentSeries,
79
+ LazyPowerSeries,
80
+ LazyPowerSeries_gcd_mixin,
81
+ LazyCompletionGradedAlgebraElement,
82
+ LazySymmetricFunction,
83
+ LazyDirichletSeries)
84
+ from sage.structure.global_options import GlobalOptions
85
+
86
+ from sage.data_structures.stream import (
87
+ Stream_zero,
88
+ Stream_function,
89
+ Stream_iterator,
90
+ Stream_exact,
91
+ Stream_uninitialized,
92
+ Stream_taylor
93
+ )
94
+
95
+ from types import GeneratorType
96
+
97
+
98
+ class LazySeriesRing(UniqueRepresentation, Parent):
99
+ """
100
+ Abstract base class for lazy series.
101
+ """
102
+ # This will never be called directly (as it is an ABC), but we copy it
103
+ # for use in other subclasses.
104
+ @staticmethod
105
+ def __classcall_private__(cls, base_ring, names, sparse=True, *args, **kwds):
106
+ """
107
+ Normalize input to ensure a unique representation.
108
+
109
+ EXAMPLES::
110
+
111
+ sage: L.<z> = LazyLaurentSeriesRing(QQ)
112
+ sage: Lp = LazyLaurentSeriesRing(QQ, 'z')
113
+ sage: L is Lp
114
+ True
115
+ """
116
+ from sage.structure.category_object import normalize_names
117
+ names = normalize_names(-1, names)
118
+ return super().__classcall__(cls, base_ring, names, sparse, *args, **kwds)
119
+
120
+ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=None, coefficients=None):
121
+ r"""
122
+ Construct a lazy series from ``x``.
123
+
124
+ INPUT:
125
+
126
+ - ``x`` -- data used to the define a series
127
+ - ``valuation`` -- integer (optional); a lower bound for the valuation
128
+ of the series
129
+ - ``degree`` -- (optional) the degree when the series is ``constant``
130
+ - ``constant`` -- (optional) the eventual constant of the series
131
+ - ``coefficients`` -- (optional) a callable that defines the
132
+ coefficients of the series; must be ``None`` if ``x`` is provided;
133
+ see note below
134
+
135
+ If ``valuation`` is specified and ``x`` is convertible into
136
+ an element of the underlying ring corresponding to series
137
+ with finite support or ``x`` is a lazy series of the same
138
+ parent, then the data is shifted so that the result has the
139
+ specified valuation.
140
+
141
+ .. WARNING::
142
+
143
+ If ``valuation`` is specified and ``x`` is a lazy series, then
144
+ the valuation will be computed. If the series ``x`` is not
145
+ known to be zero, then this will run forever.
146
+
147
+ .. NOTE::
148
+
149
+ When working over a base ring that takes callables as valid
150
+ input, then passing a function as ``x`` might be converted to
151
+ the base ring. If instead the input is to be treated as the
152
+ function giving the coefficients of the lazy series being
153
+ constructed, then use the ``coefficients`` argument in this
154
+ case and do not provide ``x``.
155
+
156
+ .. WARNING::
157
+
158
+ Polynomials, but also :class:`LazyLaurentSeries` and
159
+ :class:`LazyDirichletSeries` are callable. Therefore, an
160
+ argument ``x`` which is not convertible into an element
161
+ of the underlying ring corresponding to series with
162
+ finite support is interpreted as a function providing the
163
+ coefficients when evaluated at integers. Examples are
164
+ provided below.
165
+
166
+ .. WARNING::
167
+
168
+ If ``x`` is provided as a list, any trailing zeros are
169
+ ignored, because ``x`` is immediately converted into a
170
+ polynomial.
171
+
172
+ EXAMPLES:
173
+
174
+ If ``x`` can be converted into an element of the underlying
175
+ Laurent polynomial ring, we do this::
176
+
177
+ sage: L = LazyLaurentSeriesRing(GF(2), 'z')
178
+ sage: L(2)
179
+ 0
180
+ sage: L(3)
181
+ 1
182
+
183
+ In particular, ``x`` can be a Laurent polynomial::
184
+
185
+ sage: P.<x> = LaurentPolynomialRing(QQ)
186
+ sage: p = x^-2 + 3*x^3
187
+ sage: L.<x> = LazyLaurentSeriesRing(ZZ)
188
+ sage: L(p)
189
+ x^-2 + 3*x^3
190
+
191
+ sage: L(p, valuation=0)
192
+ 1 + 3*x^5
193
+
194
+ sage: L(p, valuation=1)
195
+ x + 3*x^6
196
+
197
+ If ``x`` is callable, its evaluation at the integers,
198
+ beginning at ``valuation``, defines the coefficients of the series::
199
+
200
+ sage: L.<z> = LazyLaurentSeriesRing(ZZ)
201
+ sage: L(lambda i: i, valuation=5, constant=1, degree=10)
202
+ 5*z^5 + 6*z^6 + 7*z^7 + 8*z^8 + 9*z^9 + z^10 + z^11 + z^12 + O(z^13)
203
+ sage: L(lambda i: i, valuation=5, constant=(1, 10))
204
+ 5*z^5 + 6*z^6 + 7*z^7 + 8*z^8 + 9*z^9 + z^10 + z^11 + z^12 + O(z^13)
205
+
206
+ sage: def g(i):
207
+ ....: if i < 0:
208
+ ....: return 1
209
+ ....: return 1 + sum(range(i + 1))
210
+ sage: e = L(g, valuation=-5); e
211
+ z^-5 + z^-4 + z^-3 + z^-2 + z^-1 + 1 + 2*z + O(z^2)
212
+ sage: f = e^-1; f
213
+ z^5 - z^6 - z^11 + O(z^12)
214
+ sage: f.coefficient(10)
215
+ 0
216
+ sage: f[20]
217
+ 9
218
+ sage: f[30]
219
+ -219
220
+
221
+ We can omit ``x``, when defining a series with constant coefficients::
222
+
223
+ sage: X = L(constant=5, degree=2); X
224
+ 5*z^2 + 5*z^3 + 5*z^4 + O(z^5)
225
+ sage: X.valuation()
226
+ 2
227
+
228
+ sage: L(valuation=2, constant=1)
229
+ z^2 + z^3 + z^4 + O(z^5)
230
+ sage: L(constant=1)
231
+ Traceback (most recent call last):
232
+ ...
233
+ ValueError: you must specify the degree for the polynomial 0
234
+
235
+ Alternatively, ``x`` can be a list of elements of the base ring.
236
+ Then these elements are read as coefficients of the terms of
237
+ degrees starting from the ``valuation``. In this case, ``constant``
238
+ may be just an element of the base ring instead of a tuple or can be
239
+ simply omitted if it is zero::
240
+
241
+ sage: f = L([1,2,3,4], valuation=-5)
242
+ sage: f
243
+ z^-5 + 2*z^-4 + 3*z^-3 + 4*z^-2
244
+ sage: g = L([1,3,5,7,9], valuation=5, constant=-1)
245
+ sage: g
246
+ z^5 + 3*z^6 + 5*z^7 + 7*z^8 + 9*z^9 - z^10 - z^11 - z^12 + O(z^13)
247
+
248
+ If ``x`` is explicitly passed as ``None``, the resulting
249
+ series is undefined. This can be used to define it
250
+ implicitly, see
251
+ :meth:`sage.rings.lazy_series.LazyModuleElement.define`::
252
+
253
+ sage: f = L(None, valuation=-1)
254
+ sage: f.define(z^-1 + z^2*f^2)
255
+ sage: f
256
+ z^-1 + 1 + 2*z + 5*z^2 + 14*z^3 + 42*z^4 + 132*z^5 + O(z^6)
257
+
258
+ We construct a lazy Laurent series over another lazy Laurent series::
259
+
260
+ sage: R.<s> = LazyLaurentSeriesRing(QQ)
261
+ sage: L.<z> = LazyLaurentSeriesRing(R)
262
+ sage: e = L(lambda n: 1/factorial(n), 0); e
263
+ 1 + z + 1/2*z^2 + 1/6*z^3 + 1/24*z^4 + 1/120*z^5 + 1/720*z^6 + O(z^7)
264
+ sage: L(lambda n: 1/(1 + s^n), 0)
265
+ 1/2 + (1 - s + s^2 - s^3 + s^4 - s^5 + s^6 + O(s^7))*z
266
+ + (1 - s^2 + s^4 - s^6 + O(s^7))*z^2
267
+ + (1 - s^3 + s^6 + O(s^7))*z^3 + (1 - s^4 + O(s^7))*z^4
268
+ + (1 - s^5 + O(s^7))*z^5 + (1 - s^6 + O(s^7))*z^6 + O(z^7)
269
+
270
+ We note that ``e`` builds correctly because ``R`` additionally
271
+ requires the valuation to be specified.
272
+
273
+ In the next example the argument is interpreted as a constant
274
+ polynomial, which happens to be a Dirichlet series::
275
+
276
+ sage: D = LazyDirichletSeriesRing(QQ, "s")
277
+ sage: L.<z> = LazyLaurentSeriesRing(D)
278
+ sage: L(lambda n: 1/factorial(n), valuation=0) # needs sage.symbolic
279
+ (1 + 1/2/2^s + 1/6/3^s + 1/24/4^s + 1/120/5^s + 1/720/6^s + 1/5040/7^s + O(1/(8^s)))
280
+
281
+ We can also specify that the given function should be
282
+ interpreted as the coefficients of the Laurent series::
283
+
284
+ sage: L(coefficients=lambda n: 1/factorial(n), valuation=0) # needs sage.symbolic
285
+ 1 + z + 1/2*z^2 + 1/6*z^3 + 1/24*z^4 + 1/120*z^5 + 1/720*z^6 + O(z^7)
286
+
287
+ When the argument ``x`` is callable and not convertible into
288
+ an element of the underlying ring of series of finite
289
+ support, it is evaluated at integers to compute the
290
+ coefficients::
291
+
292
+ sage: R.<q> = QQ[]
293
+ sage: D = LazyDirichletSeriesRing(ZZ, 't')
294
+ sage: D(1+2*q) # needs sage.symbolic
295
+ 3 + 5/2^t + 7/3^t + 9/4^t + 11/5^t + 13/6^t + 15/7^t + O(1/(8^t))
296
+
297
+ In this example, the Dirichlet series ``m`` is considered as an
298
+ element in the base ring::
299
+
300
+ sage: m = D(moebius)
301
+ sage: s = L(m, valuation=0) # needs sage.symbolic
302
+ sage: s[0] # needs sage.symbolic
303
+ 1 - 1/(2^s) - 1/(3^s) - 1/(5^s) + 1/(6^s) - 1/(7^s) + O(1/(8^s))
304
+ sage: s[1] # needs sage.symbolic
305
+ 0
306
+
307
+ Converting various series from a univariate power series::
308
+
309
+ sage: # needs sage.rings.finite_rings
310
+ sage: L = LazyLaurentSeriesRing(GF(2), 'z')
311
+ sage: R = LazyPowerSeriesRing(ZZ, 'z')
312
+ sage: L.has_coerce_map_from(R)
313
+ True
314
+ sage: L(R(lambda n: n))
315
+ z + z^3 + z^5 + z^7 + O(z^8)
316
+ sage: L(R([2,4,6])) == L.zero()
317
+ True
318
+ sage: L(R([2,4,6], valuation=2, constant=4)) == L.zero()
319
+ True
320
+ sage: L(R([2,4,6], valuation=2, constant=5))
321
+ z^5 + z^6 + z^7 + O(z^8)
322
+ sage: L(R([2,3,4], valuation=2, constant=4))
323
+ z^3
324
+ sage: L(R([2,3,4], valuation=2, constant=5))
325
+ z^3 + z^5 + z^6 + z^7 + O(z^8)
326
+
327
+ Can only convert from known to be constant multivariate power series::
328
+
329
+ sage: L = LazyLaurentSeriesRing(QQ, 'z')
330
+ sage: R.<x,y> = LazyPowerSeriesRing(QQ)
331
+ sage: L(R(2))
332
+ 2
333
+ sage: L(R.zero())
334
+ 0
335
+ sage: L(x)
336
+ Traceback (most recent call last):
337
+ ...
338
+ ValueError: unable to convert ...
339
+ sage: L(1 / (1 - x - y))
340
+ Traceback (most recent call last):
341
+ ...
342
+ ValueError: unable to convert ...
343
+ sage: P.<x,y> = QQ[]
344
+ sage: f = R(lambda n: (x+y)^n if n == 0 else P.zero()); f
345
+ 1 + O(x,y)^7
346
+ sage: L(f)
347
+ Traceback (most recent call last):
348
+ ...
349
+ ValueError: unable to convert ...
350
+
351
+ Converting from the corresponding rational functions::
352
+
353
+ sage: L = LazyLaurentSeriesRing(QQ, 't')
354
+ sage: tt = L.gen()
355
+ sage: R.<t> = LaurentPolynomialRing(QQ)
356
+ sage: f = (1 + t) / (1 + t + t^2); f
357
+ (t + 1)/(t^2 + t + 1)
358
+ sage: f.parent()
359
+ Fraction Field of Univariate Polynomial Ring in t over Rational Field
360
+ sage: L(f)
361
+ 1 - t^2 + t^3 - t^5 + t^6 + O(t^7)
362
+ sage: L(f) == (1 + tt) / (1 + tt + tt^2)
363
+ True
364
+ sage: f = (3 + t) / (t^3 - t^5); f
365
+ (-t - 3)/(t^5 - t^3)
366
+ sage: f.parent()
367
+ Fraction Field of Univariate Polynomial Ring in t over Rational Field
368
+ sage: L(f)
369
+ 3*t^-3 + t^-2 + 3*t^-1 + 1 + 3*t + t^2 + 3*t^3 + O(t^4)
370
+ sage: L(f) - (3 + tt) / (tt^3 - tt^5)
371
+ O(t^4)
372
+
373
+ TESTS:
374
+
375
+ Checking the valuation is consistent::
376
+
377
+ sage: L.<z> = LazyLaurentSeriesRing(ZZ)
378
+ sage: L([0,0,2,3], valuation=-4)
379
+ 2*z^-4 + 3*z^-3
380
+ sage: L(range(5), valuation=-4)
381
+ z^-4 + 2*z^-3 + 3*z^-2 + 4*z^-1
382
+ sage: P.<x> = ZZ[]
383
+ sage: L(x^2 + x^5, valuation=-4)
384
+ z^-4 + z^-1
385
+ sage: L(1, valuation=-4)
386
+ z^-4
387
+ sage: L(L(1), valuation=-4)
388
+ z^-4
389
+ sage: L(1/(1-z), valuation=-4)
390
+ z^-4 + z^-3 + z^-2 + O(z^-1)
391
+ sage: L(z^-3/(1-z), valuation=-4)
392
+ z^-4 + z^-3 + z^-2 + O(z^-1)
393
+ sage: L(z^3/(1-z), valuation=-4)
394
+ z^-4 + z^-3 + z^-2 + O(z^-1)
395
+
396
+ sage: L(z^3/(1-z), valuation=0)
397
+ 1 + z + z^2 + O(z^3)
398
+
399
+ sage: L(lambda n: 1/(n+1), degree=3)
400
+ Traceback (most recent call last):
401
+ ...
402
+ ValueError: the valuation must be specified
403
+
404
+ sage: L(5, valuation=3.1)
405
+ Traceback (most recent call last):
406
+ ...
407
+ ValueError: the valuation must be an integer
408
+
409
+ sage: L(5, valuation=6/2)
410
+ 5*z^3
411
+
412
+ Checking that series are not interpreted as coefficients when
413
+ they can be interpreted as series::
414
+
415
+ sage: P.<s> = ZZ[]
416
+ sage: L.<z> = LazyLaurentSeriesRing(ZZ)
417
+ sage: M.<w> = LazyLaurentSeriesRing(QQ)
418
+ sage: L(M(s^2 + s^5), valuation=-4)
419
+ z^-4 + z^-1
420
+
421
+ sage: D = LazyDirichletSeriesRing(ZZ, "s")
422
+ sage: E = LazyDirichletSeriesRing(QQ, "t")
423
+ sage: D(E([1,2,3])) # needs sage.symbolic
424
+ 1 + 2/2^s + 3/3^s
425
+
426
+ This gives zero::
427
+
428
+ sage: L = LazyLaurentSeriesRing(ZZ, 'z')
429
+ sage: L(lambda n: 0, degree=3, valuation=0)
430
+ 0
431
+ sage: L(L.zero(), degree=3)
432
+ 0
433
+ sage: L(L.zero(), degree=3, valuation=2)
434
+ 0
435
+ sage: L(L.zero(), degree=3, constant=0)
436
+ 0
437
+ sage: L(L.zero(), degree=3, valuation=2, constant=0)
438
+ 0
439
+
440
+ This does not::
441
+
442
+ sage: L(lambda n: 0, degree=3, constant=1, valuation=0)
443
+ z^3 + z^4 + z^5 + O(z^6)
444
+ sage: L(L.zero(), degree=-3, constant=1)
445
+ z^-3 + z^-2 + z^-1 + O(1)
446
+ sage: L(L.zero(), valuation=2, constant=1)
447
+ z^2 + z^3 + z^4 + O(z^5)
448
+
449
+ This raises an error::
450
+
451
+ sage: L(lambda n: 0, valuation=3, constant=1)
452
+ Traceback (most recent call last):
453
+ ...
454
+ ValueError: constant may only be specified if the degree is specified
455
+
456
+ We support the old input format for ``constant``::
457
+
458
+ sage: f = L(lambda i: i, valuation=-3, constant=-1, degree=3)
459
+ sage: g = L(lambda i: i, valuation=-3, constant=(-1,3))
460
+ sage: f == g
461
+ True
462
+ sage: g = L(lambda i: i, -3, (-1,3))
463
+ sage: f == g
464
+ True
465
+
466
+ We support passing a generator::
467
+
468
+ sage: L(filter(is_odd, NN), -3)
469
+ z^-3 + 3*z^-2 + 5*z^-1 + 7 + 9*z + 11*z^2 + 13*z^3 + O(z^4)
470
+ """
471
+ if valuation is not None and valuation not in ZZ:
472
+ raise ValueError("the valuation must be an integer")
473
+
474
+ if x is None and coefficients is None:
475
+ if valuation is None:
476
+ raise ValueError("the valuation must be specified")
477
+ return self.element_class(self, Stream_uninitialized(valuation))
478
+
479
+ # WARNING: if x is not explicitly specified as None, it is
480
+ # set to 0 by Parent.__call__
481
+ if coefficients is not None and (x is not None and (not isinstance(x, int) or x)):
482
+ raise ValueError("coefficients must be None if x is provided")
483
+
484
+ BR = self._internal_poly_ring.base_ring() # this is the ring containing the elements of the stream
485
+ if isinstance(constant, (tuple, list)):
486
+ constant, degree = constant
487
+ if isinstance(degree, (tuple, list)):
488
+ constant, degree = degree
489
+ if constant is not None:
490
+ constant = BR(constant)
491
+
492
+ if coefficients is None:
493
+ # Try to build stuff using the internal polynomial ring constructor
494
+ R = self._internal_poly_ring
495
+
496
+ try:
497
+ x = R(x)
498
+ except (TypeError, ValueError):
499
+ pass
500
+
501
+ # If x has been converted to the internal polynomial ring
502
+ if parent(x) is R:
503
+ if not x and not constant:
504
+ return self.zero()
505
+ if x and valuation is not None:
506
+ x = x.shift(valuation - x.valuation())
507
+ if degree is None and not x:
508
+ if valuation is None:
509
+ raise ValueError("you must specify the degree for the polynomial 0")
510
+ degree = valuation
511
+ if not x:
512
+ coeff_stream = Stream_exact([], order=degree, constant=constant)
513
+ return self.element_class(self, coeff_stream)
514
+ initial_coefficients = [x[i] for i in range(x.valuation(), x.degree() + 1)]
515
+ coeff_stream = Stream_exact(initial_coefficients,
516
+ order=x.valuation(), degree=degree, constant=constant)
517
+ return self.element_class(self, coeff_stream)
518
+
519
+ # Handle when it is a lazy series
520
+ if isinstance(x, self.Element):
521
+ # If x is known to be 0
522
+ if isinstance(x._coeff_stream, Stream_zero):
523
+ if not constant:
524
+ if self is parent(x):
525
+ return x
526
+ return self.element_class(self, x._coeff_stream)
527
+ if degree is None:
528
+ if valuation is None:
529
+ raise ValueError("you must specify the degree for the polynomial 0")
530
+ degree = valuation
531
+ coeff_stream = Stream_exact([], order=degree, constant=constant)
532
+ return self.element_class(self, coeff_stream)
533
+
534
+ # Make the result exact
535
+ if degree is not None:
536
+ # truncate the series and then possibly make constant
537
+ x_val = x._coeff_stream.order()
538
+ if not valuation:
539
+ valuation = x_val
540
+ initial_coefficients = [x[x_val+i] for i in range(degree-valuation)]
541
+ if not any(initial_coefficients):
542
+ if not constant:
543
+ return self.zero()
544
+ # We learned some stuff about x; pass it along
545
+ x._coeff_stream._approximate_order += len(initial_coefficients)
546
+ initial_coefficients = []
547
+ coeff_stream = Stream_exact(initial_coefficients,
548
+ order=valuation, degree=degree, constant=constant)
549
+ return self.element_class(self, coeff_stream)
550
+
551
+ # We are just possibly shifting the result
552
+ ret = self.element_class(self, x._coeff_stream)
553
+ if valuation is None:
554
+ return ret
555
+ return ret.shift(valuation - x._coeff_stream.order())
556
+
557
+ # Handle when it is a power series
558
+ if isinstance(x, LazyPowerSeries):
559
+ stream = x._coeff_stream
560
+ if isinstance(stream, Stream_zero):
561
+ return self.zero()
562
+ elif isinstance(stream, Stream_exact):
563
+ if x.parent()._arity != 1:
564
+ # Special case for constant series
565
+ if stream._degree == 1:
566
+ return self(BR(stream[0]))
567
+ else:
568
+ coeffs = [BR(val) for val in stream._initial_coefficients]
569
+ valuation = stream._approximate_order
570
+ for i, c in enumerate(coeffs):
571
+ if c:
572
+ valuation += i
573
+ coeffs = coeffs[i:]
574
+ break
575
+ else:
576
+ valuation += len(coeffs)
577
+ coeffs = []
578
+ return self(coeffs,
579
+ degree=stream._degree,
580
+ constant=BR(stream._constant),
581
+ valuation=valuation)
582
+ elif x.parent()._arity == 1:
583
+ return self.element_class(self, stream)
584
+ raise ValueError(f"unable to convert {x} into {self}")
585
+
586
+ # Check if we can realize the input as a rational function
587
+ try:
588
+ FF = self._laurent_poly_ring.fraction_field()
589
+ x = FF(x)
590
+ except (TypeError, ValueError, AttributeError):
591
+ pass
592
+ else:
593
+ return self(x.numerator()) / self(x.denominator())
594
+
595
+ else:
596
+ x = coefficients
597
+
598
+ if callable(x) or isinstance(x, (GeneratorType, map, filter)):
599
+ if valuation is None:
600
+ raise ValueError("the valuation must be specified")
601
+ if degree is None:
602
+ if constant is not None:
603
+ raise ValueError("constant may only be specified if the degree is specified")
604
+ if callable(x):
605
+ coeff_stream = Stream_function(lambda i: BR(x(i)), self._sparse, valuation)
606
+ else:
607
+ coeff_stream = Stream_iterator(map(BR, _skip_leading_zeros(x)), valuation)
608
+ return self.element_class(self, coeff_stream)
609
+
610
+ # degree is not None
611
+ if constant is None:
612
+ constant = BR.zero()
613
+ if callable(x):
614
+ p = [BR(x(i)) for i in range(valuation, degree)]
615
+ else:
616
+ p = [BR(c) for c, _ in zip(_skip_leading_zeros(x), range(valuation, degree))]
617
+ if not any(p) and not constant:
618
+ return self.zero()
619
+ coeff_stream = Stream_exact(p, order=valuation, constant=constant, degree=degree)
620
+ return self.element_class(self, coeff_stream)
621
+
622
+ raise ValueError(f"unable to convert {x} into {self}")
623
+
624
+ def undefined(self, valuation=None, name=None):
625
+ r"""
626
+ Return an uninitialized series.
627
+
628
+ INPUT:
629
+
630
+ - ``valuation`` -- integer; a lower bound for the valuation
631
+ of the series
632
+ - ``name`` -- string; a name that refers to the undefined
633
+ stream in error messages
634
+
635
+ Power series can be defined recursively (see
636
+ :meth:`sage.rings.lazy_series.LazyModuleElement.define` for
637
+ more examples).
638
+
639
+ .. SEEALSO::
640
+
641
+ :meth:`sage.rings.padics.generic_nodes.pAdicRelaxedGeneric.unknown`
642
+
643
+ EXAMPLES::
644
+
645
+ sage: L.<z> = LazyPowerSeriesRing(QQ)
646
+ sage: s = L.undefined(1)
647
+ sage: s.define(z + (s^2+s(z^2))/2)
648
+ sage: s
649
+ z + z^2 + z^3 + 2*z^4 + 3*z^5 + 6*z^6 + 11*z^7 + O(z^8)
650
+
651
+ Alternatively::
652
+
653
+ sage: L.<z> = LazyLaurentSeriesRing(QQ)
654
+ sage: f = L(None, valuation=-1)
655
+ sage: f.define(z^-1 + z^2*f^2)
656
+ sage: f
657
+ z^-1 + 1 + 2*z + 5*z^2 + 14*z^3 + 42*z^4 + 132*z^5 + O(z^6)
658
+ """
659
+ if valuation is None:
660
+ valuation = self._minimal_valuation
661
+ coeff_stream = Stream_uninitialized(valuation, name=name)
662
+ return self.element_class(self, coeff_stream)
663
+
664
+ unknown = undefined
665
+
666
+ def _terms_of_degree(self, n, R):
667
+ r"""
668
+ Return the list of terms occurring in a coefficient of degree
669
+ ``n`` such that coefficients are in the ring ``R``.
670
+
671
+ For example, if ``self`` is a univariate Laurent, power, or
672
+ Dirichlet series, this is the list containing the one of the
673
+ base ring. If ``self`` is a multivariate power series, this
674
+ is the list of monomials of total degree ``n``. If ``self``
675
+ is a lazy symmetric function, this is the list of basis
676
+ elements of total degree ``n``.
677
+
678
+ EXAMPLES::
679
+
680
+ sage: # needs sage.combinat sage.modules
681
+ sage: s = SymmetricFunctions(ZZ).s()
682
+ sage: L = LazySymmetricFunctions(s)
683
+ sage: m = L._terms_of_degree(3, ZZ); m
684
+ [s[3], s[2, 1], s[1, 1, 1]]
685
+ """
686
+ raise NotImplementedError
687
+
688
+ def define_implicitly(self, series, equations, max_lookahead=1):
689
+ r"""
690
+ Define series by solving functional equations.
691
+
692
+ INPUT:
693
+
694
+ - ``series`` -- list of undefined series or pairs each
695
+ consisting of a series and its initial values
696
+ - ``equations`` -- list of equations defining the series
697
+ - ``max_lookahead``-- (default: ``1``); a positive integer
698
+ specifying how many elements beyond the currently known
699
+ (i.e., approximate) order of each equation to extract
700
+ linear equations from
701
+
702
+ EXAMPLES::
703
+
704
+ sage: # needs sage.modules
705
+ sage: L.<z> = LazyPowerSeriesRing(QQ)
706
+ sage: f = L.undefined(0)
707
+ sage: F = diff(f, 2)
708
+ sage: L.define_implicitly([(f, [1, 0])], [F + f])
709
+ sage: f
710
+ 1 - 1/2*z^2 + 1/24*z^4 - 1/720*z^6 + O(z^7)
711
+ sage: cos(z)
712
+ 1 - 1/2*z^2 + 1/24*z^4 - 1/720*z^6 + O(z^7)
713
+ sage: F
714
+ -1 + 1/2*z^2 - 1/24*z^4 + 1/720*z^6 + O(z^7)
715
+
716
+ sage: L.<z> = LazyPowerSeriesRing(QQ)
717
+ sage: f = L.undefined(0)
718
+ sage: L.define_implicitly([f], [2*z*f(z^3) + z*f^3 - 3*f + 3])
719
+ sage: f
720
+ 1 + z + z^2 + 2*z^3 + 5*z^4 + 11*z^5 + 28*z^6 + O(z^7)
721
+
722
+ From Exercise 6.63b in [EnumComb2]_::
723
+
724
+ sage: # needs sage.modules
725
+ sage: g = L.undefined()
726
+ sage: z1 = z*diff(g, z)
727
+ sage: z2 = z1 + z^2 * diff(g, z, 2)
728
+ sage: z3 = z1 + 3 * z^2 * diff(g, z, 2) + z^3 * diff(g, z, 3)
729
+ sage: e1 = g^2 * z3 - 15*g*z1*z2 + 30*z1^3
730
+ sage: e2 = g * z2 - 3 * z1^2
731
+ sage: e3 = g * z2 - 3 * z1^2
732
+ sage: e = e1^2 + 32 * e2^3 - g^10 * e3^2
733
+ sage: L.define_implicitly([(g, [1, 2])], [e])
734
+ sage: sol = L(lambda n: 1 if not n else (2 if is_square(n) else 0)); sol
735
+ 1 + 2*z + 2*z^4 + O(z^7)
736
+ sage: all(g[i] == sol[i] for i in range(50))
737
+ True
738
+
739
+ Some more examples over different rings::
740
+
741
+ sage: # needs sage.symbolic
742
+ sage: L.<z> = LazyPowerSeriesRing(SR)
743
+ sage: G = L.undefined(0)
744
+ sage: L.define_implicitly([(G, [ln(2)])], [diff(G) - exp(-G(-z))])
745
+ sage: G
746
+ log(2) + z + 1/2*z^2 + (-1/12*z^4) + 1/45*z^6 + O(z^7)
747
+ sage: L.<z> = LazyPowerSeriesRing(RR)
748
+ sage: G = L.undefined(0)
749
+ sage: L.define_implicitly([(G, [log(2)])], [diff(G) - exp(-G(-z))])
750
+ sage: G
751
+ 0.693147180559945 + 1.00000000000000*z + 0.500000000000000*z^2
752
+ - 0.0833333333333333*z^4 + 0.0222222222222222*z^6 + O(1.00000000000000*z^7)
753
+
754
+ We solve the recurrence relation in (3.12) of Prellberg and Brak
755
+ :doi:`10.1007/BF02183685`::
756
+
757
+ sage: # needs sage.modules
758
+ sage: q, y = QQ['q,y'].fraction_field().gens()
759
+ sage: L.<x> = LazyPowerSeriesRing(q.parent())
760
+ sage: R = L.undefined()
761
+ sage: L.define_implicitly([(R, [0])], [(1-q*x)*R - (y*q*x+y)*R(q*x) - q*x*R*R(q*x) - x*y*q])
762
+ sage: R[0]
763
+ 0
764
+ sage: R[1]
765
+ (-q*y)/(q*y - 1)
766
+ sage: R[2]
767
+ (q^3*y^2 + q^2*y)/(q^3*y^2 - q^2*y - q*y + 1)
768
+ sage: R[3].factor()
769
+ (-1) * y * q^3 * (q*y - 1)^-2 * (q^2*y - 1)^-1 * (q^3*y - 1)^-1
770
+ * (q^4*y^3 + q^3*y^2 + q^2*y^2 - q^2*y - q*y - 1)
771
+ sage: Rp = L.undefined(1)
772
+ sage: L.define_implicitly([Rp], [(y*q*x+y)*Rp(q*x) + q*x*Rp*Rp(q*x) + x*y*q - (1-q*x)*Rp])
773
+ sage: all(R[n] == Rp[n] for n in range(7))
774
+ True
775
+
776
+ Another example::
777
+
778
+ sage: # needs sage.modules
779
+ sage: L.<z> = LazyPowerSeriesRing(QQ["x,y,f1,f2"].fraction_field())
780
+ sage: L.base_ring().inject_variables()
781
+ Defining x, y, f1, f2
782
+ sage: F = L.undefined()
783
+ sage: L.define_implicitly([(F, [0, f1, f2])], [F(2*z) - (1+exp(x*z)+exp(y*z))*F - exp((x+y)*z)*F(-z)])
784
+ sage: F
785
+ f1*z + f2*z^2 + ((-1/6*x*y*f1+1/3*x*f2+1/3*y*f2)*z^3)
786
+ + ((-1/24*x^2*y*f1-1/24*x*y^2*f1+1/12*x^2*f2+1/12*x*y*f2+1/12*y^2*f2)*z^4)
787
+ + ... + O(z^8)
788
+ sage: sol = 1/(x-y)*((2*f2-y*f1)*(exp(x*z)-1)/x - (2*f2-x*f1)*(exp(y*z)-1)/y)
789
+ sage: F - sol
790
+ O(z^7)
791
+
792
+ We need to specify the initial values for the degree 1 and 2
793
+ components to get a unique solution in the previous example::
794
+
795
+ sage: # needs sage.modules
796
+ sage: L.<z> = LazyPowerSeriesRing(QQ['x','y','f1'].fraction_field())
797
+ sage: L.base_ring().inject_variables()
798
+ Defining x, y, f1
799
+ sage: F = L.undefined()
800
+ sage: L.define_implicitly([F], [F(2*z) - (1+exp(x*z)+exp(y*z))*F - exp((x+y)*z)*F(-z)])
801
+ sage: F
802
+ <repr(...) failed: ValueError: could not determine any coefficients:
803
+ coefficient [3]: 6*series[3] + (-2*x - 2*y)*series[2] + (x*y)*series[1] == 0>
804
+
805
+ Let us now try to only specify the degree 0 and degree 1
806
+ components. We will see that this is still not enough to
807
+ remove the ambiguity, so an error is raised. However, we
808
+ will see that the dependence on ``series[1]`` disappears.
809
+ The equation which has no unique solution is now
810
+ ``6*series[3] + (-2*x - 2*y)*series[2] + (x*y*f1) == 0``.::
811
+
812
+ sage: # needs sage.modules
813
+ sage: F = L.undefined()
814
+ sage: L.define_implicitly([(F, [0, f1])], [F(2*z) - (1+exp(x*z)+exp(y*z))*F - exp((x+y)*z)*F(-z)])
815
+ sage: F
816
+ <repr(...) failed: ValueError: could not determine any coefficients:
817
+ coefficient [3]: ... == 0>
818
+
819
+ (Note that the order of summands of the equation in the error
820
+ message is not deterministic.)
821
+
822
+ Laurent series examples::
823
+
824
+ sage: # needs sage.modules
825
+ sage: L.<z> = LazyLaurentSeriesRing(QQ)
826
+ sage: f = L.undefined(-1)
827
+ sage: L.define_implicitly([(f, [5])], [2+z*f(z^2) - f])
828
+ sage: f
829
+ 5*z^-1 + 2 + 2*z + 2*z^3 + O(z^6)
830
+ sage: 2 + z*f(z^2) - f
831
+ O(z^6)
832
+
833
+ sage: g = L.undefined(-2)
834
+ sage: L.define_implicitly([(g, [5])], [2+z*g(z^2) - g])
835
+ sage: g
836
+ <repr(...) failed: ValueError: no solution as the coefficient in degree -3 of the equation is 5 != 0>
837
+
838
+ A bivariate example::
839
+
840
+ sage: # needs sage.combinat sage.modules
841
+ sage: L.<x, y> = LazyPowerSeriesRing(QQ)
842
+ sage: B = L.undefined()
843
+ sage: eq = y*B^2 + 1 - B(x, x-y)
844
+ sage: L.define_implicitly([B], [eq])
845
+ sage: B
846
+ 1 + (x-y) + (2*x*y-2*y^2) + (4*x^2*y-7*x*y^2+3*y^3)
847
+ + (2*x^3*y+6*x^2*y^2-18*x*y^3+10*y^4)
848
+ + (30*x^3*y^2-78*x^2*y^3+66*x*y^4-18*y^5)
849
+ + (28*x^4*y^2-12*x^3*y^3-128*x^2*y^4+180*x*y^5-68*y^6) + O(x,y)^7
850
+
851
+ Knödel walks::
852
+
853
+ sage: # needs sage.combinat sage.modules
854
+ sage: L.<z, x> = LazyPowerSeriesRing(QQ)
855
+ sage: F = L.undefined()
856
+ sage: eq = F(z, x)*(x^2*z-x+z) - (z - x*z^2 - x^2*z^2)*F(z, 0) + x
857
+ sage: L.define_implicitly([F], [eq])
858
+ sage: F
859
+ 1 + (2*z^2+z*x) + (z^3+z^2*x) + (5*z^4+3*z^3*x+z^2*x^2)
860
+ + (5*z^5+4*z^4*x+z^3*x^2) + (15*z^6+10*z^5*x+4*z^4*x^2+z^3*x^3)
861
+ + O(z,x)^7
862
+
863
+ Bicolored rooted trees with black and white roots::
864
+
865
+ sage: # needs sage.combinat sage.modules
866
+ sage: L.<x, y> = LazyPowerSeriesRing(QQ)
867
+ sage: A = L.undefined()
868
+ sage: B = L.undefined()
869
+ sage: L.define_implicitly([A, B], [A - x*exp(B), B - y*exp(A)])
870
+ sage: A
871
+ x + x*y + (x^2*y+1/2*x*y^2) + (1/2*x^3*y+2*x^2*y^2+1/6*x*y^3)
872
+ + (1/6*x^4*y+3*x^3*y^2+2*x^2*y^3+1/24*x*y^4)
873
+ + (1/24*x^5*y+8/3*x^4*y^2+27/4*x^3*y^3+4/3*x^2*y^4+1/120*x*y^5)
874
+ + O(x,y)^7
875
+
876
+ sage: # needs sage.combinat sage.modules
877
+ sage: h = SymmetricFunctions(QQ).h()
878
+ sage: S = LazySymmetricFunctions(h)
879
+ sage: E = S(lambda n: h[n])
880
+ sage: T = LazySymmetricFunctions(tensor([h, h]))
881
+ sage: X = tensor([h[1],h[[]]])
882
+ sage: Y = tensor([h[[]],h[1]])
883
+ sage: A = T.undefined()
884
+ sage: B = T.undefined()
885
+ sage: T.define_implicitly([A, B], [A - X*E(B), B - Y*E(A)])
886
+ sage: A[:3]
887
+ [h[1] # h[], h[1] # h[1]]
888
+
889
+ Permutations with two kinds of labels such that each cycle
890
+ contains at least one element of each kind (defined
891
+ implicitly to have a test)::
892
+
893
+ sage: # needs sage.combinat sage.modules
894
+ sage: p = SymmetricFunctions(QQ).p()
895
+ sage: S = LazySymmetricFunctions(p)
896
+ sage: P = S(lambda n: sum(p[la] for la in Partitions(n)))
897
+ sage: T = LazySymmetricFunctions(tensor([p, p]))
898
+ sage: X = tensor([p[1],p[[]]])
899
+ sage: Y = tensor([p[[]],p[1]])
900
+ sage: A = T.undefined()
901
+ sage: T.define_implicitly([A], [P(X)*P(Y)*A - P(X+Y)])
902
+ sage: A[:4]
903
+ [p[] # p[], 0, p[1] # p[1], p[1] # p[1, 1] + p[1, 1] # p[1]]
904
+
905
+ The Frobenius character of labelled Dyck words::
906
+
907
+ sage: # needs sage.combinat sage.modules
908
+ sage: h = SymmetricFunctions(QQ).h()
909
+ sage: L.<t, u> = LazyPowerSeriesRing(h.fraction_field())
910
+ sage: D = L.undefined()
911
+ sage: s1 = L.sum(lambda n: h[n]*t^(n+1)*u^(n-1), 1)
912
+ sage: L.define_implicitly([D], [u*D - u - u*s1*D - t*(D - D(t, 0))])
913
+ sage: D
914
+ h[] + h[1]*t^2 + ((h[1,1]+h[2])*t^4+h[2]*t^3*u)
915
+ + ((h[1,1,1]+3*h[2,1]+h[3])*t^6+(2*h[2,1]+h[3])*t^5*u+h[3]*t^4*u^2)
916
+ + O(t,u)^7
917
+
918
+ TESTS::
919
+
920
+ sage: # needs sage.modules
921
+ sage: L.<z> = LazyPowerSeriesRing(QQ)
922
+ sage: f = L.undefined(1)
923
+ sage: L.define_implicitly([f], [log(1+f) - ~(1 + f) + 1])
924
+ sage: f
925
+ O(z^8)
926
+
927
+ sage: # needs sage.modules
928
+ sage: f = L.undefined(0)
929
+ sage: fp = f.derivative()
930
+ sage: g = L(lambda n: 0 if n < 10 else 1, 0)
931
+ sage: L.define_implicitly([f], [f.derivative() * g + f])
932
+ sage: f[0]
933
+ 0
934
+ sage: fp[0]
935
+ 0
936
+ sage: fp[1]
937
+ 0
938
+ sage: fp[2]
939
+ 0
940
+ sage: f[1]
941
+ 0
942
+
943
+ Some systems of coupled functional equations::
944
+
945
+ sage: # needs sage.modules
946
+ sage: L.<z> = LazyPowerSeriesRing(QQ)
947
+ sage: A = L.undefined()
948
+ sage: B = L.undefined()
949
+ sage: L.define_implicitly([A, B], [A - B, A + B + 2])
950
+ sage: A
951
+ -1 + O(z^7)
952
+ sage: B
953
+ -1 + O(z^7)
954
+
955
+ sage: # needs sage.modules
956
+ sage: L.<z> = LazyPowerSeriesRing(QQ)
957
+ sage: A = L.undefined()
958
+ sage: B = L.undefined()
959
+ sage: FA = A^2 + B - 2 - z*B
960
+ sage: FB = B^2 - A
961
+ sage: L.define_implicitly([(A, [1]), (B, [1])], [FA, FB])
962
+ sage: A^2 + B - 2 - z*B
963
+ O(z^7)
964
+ sage: B^2 - A
965
+ O(z^7)
966
+
967
+ sage: # needs sage.modules
968
+ sage: L.<z> = LazyPowerSeriesRing(QQ)
969
+ sage: A = L.undefined()
970
+ sage: B = L.undefined()
971
+ sage: FA = A^2 + B^2 - 2 - z*B
972
+ sage: FB = B^3 + 2*A^3 - 3 - z*(A + B)
973
+ sage: L.define_implicitly([(A, [1]), (B, [1])], [FA, FB])
974
+ sage: A^2 + B^2 - 2 - z*B
975
+ O(z^7)
976
+ sage: B^3 + 2*A^3 - 3 - z*(A + B)
977
+ O(z^7)
978
+
979
+ sage: # needs sage.modules
980
+ sage: L.<z> = LazyPowerSeriesRing(QQ)
981
+ sage: A = L.undefined(valuation=3)
982
+ sage: B = L.undefined(valuation=2)
983
+ sage: C = L.undefined(valuation=2)
984
+ sage: FA = (A^2 + B^2)*z^2
985
+ sage: FB = A*B*z
986
+ sage: FC = (A + B + C)*z^2
987
+ sage: L.define_implicitly([A, B, C], [FA, FB, FC])
988
+ sage: A
989
+ O(z^10)
990
+ sage: B
991
+ O(z^16)
992
+ sage: C
993
+ O(z^23)
994
+
995
+ sage: # needs sage.modules
996
+ sage: L.<z> = LazyPowerSeriesRing(QQ)
997
+ sage: A = L.undefined()
998
+ sage: B = L.undefined()
999
+ sage: C = L.undefined()
1000
+ sage: L.define_implicitly([A, B, C], [B - C - 1, B*z + 2*C + 1, A + 2*C + 1])
1001
+ sage: A + 2*C + 1
1002
+ O(z^7)
1003
+
1004
+ The following system does not determine `B`, but the solver
1005
+ will inductively discover that each coefficient of `A` must
1006
+ be zero. Therefore, asking for a coefficient of `B` will
1007
+ loop forever::
1008
+
1009
+ sage: # needs sage.modules
1010
+ sage: L.<z> = LazyPowerSeriesRing(QQ)
1011
+ sage: A = L.undefined()
1012
+ sage: B = L.undefined()
1013
+ sage: C = L.undefined()
1014
+ sage: D = L.undefined()
1015
+ sage: L.define_implicitly([(A, [0,0,0]), (B, [0,0]), (C, [0,0]), (D, [0,0])], [C^2 + D^2, A + B + C + D, A*D])
1016
+ sage: B[2] # not tested
1017
+
1018
+ A bivariate example involving composition of series::
1019
+
1020
+ sage: # needs sage.modules
1021
+ sage: R.<z,q> = LazyPowerSeriesRing(QQ)
1022
+ sage: g = R.undefined()
1023
+ sage: R.define_implicitly([g], [g - (z*q + z*g*~(1-g))])
1024
+ sage: g
1025
+ z*q + z^2*q + z^3*q + (z^4*q+z^3*q^2) + (z^5*q+3*z^4*q^2) + O(z,q)^7
1026
+
1027
+ The following does not work, because the equations
1028
+ determining the coefficients come in bad order::
1029
+
1030
+ sage: # needs sage.modules
1031
+ sage: L.<x,y,t> = LazyPowerSeriesRing(QQ)
1032
+ sage: A = L.undefined(name="A")
1033
+ sage: B = L.undefined(name="B")
1034
+ sage: eq0 = t*x*y*B(0, 0, t) + (t - x*y)*A(x, y, t) + x*y - t*A(0, y, t)
1035
+ sage: eq1 = (t*x-t)*B(0, y, t) + (t - x*y)*B(x, y, t)
1036
+ sage: L.define_implicitly([A, B], [eq0, eq1])
1037
+ sage: A[1]
1038
+ Traceback (most recent call last):
1039
+ ...
1040
+ ValueError: could not determine any coefficients:
1041
+ equation 0:
1042
+ coefficient [x*y*t]: A[x*y] - A[t] == 0
1043
+ equation 1:
1044
+ coefficient [x*t^2]: B[x*t] + B[t] == 0
1045
+ coefficient [x*y*t]: B[x*y] - B[t] == 0
1046
+
1047
+ Check the error message in the case of symmetric functions::
1048
+
1049
+ sage: # needs sage.modules
1050
+ sage: p = SymmetricFunctions(QQ).p()
1051
+ sage: T = LazySymmetricFunctions(tensor([p, p]))
1052
+ sage: X = tensor([p[1],p[[]]])
1053
+ sage: Y = tensor([p[[]],p[1]])
1054
+ sage: A = T.undefined(name="A")
1055
+ sage: B = T.undefined(name="B")
1056
+ sage: T.define_implicitly([A, B], [X*A - Y*B])
1057
+ sage: A
1058
+ <repr(...) failed: ValueError: could not determine any coefficients:
1059
+ coefficient [p[1] # p[1]]: -B[p[1] # p[]] + A[p[] # p[1]] == 0>
1060
+
1061
+ An example we cannot solve because we only look at the next
1062
+ non-vanishing equations::
1063
+
1064
+ sage: # needs sage.modules
1065
+ sage: L.<x> = LazyPowerSeriesRing(QQ)
1066
+ sage: A = L.undefined()
1067
+ sage: eq1 = diff(A, x) + diff(A, x, 2)
1068
+ sage: eq2 = A + diff(A, x) + diff(A, x, 2)
1069
+ sage: L.define_implicitly([A], [eq1, eq2])
1070
+ sage: A[1]
1071
+ Traceback (most recent call last):
1072
+ ...
1073
+ ValueError: could not determine any coefficients:
1074
+ equation 0:
1075
+ coefficient [0]: 2*series[2] + series[1] == 0
1076
+ equation 1:
1077
+ coefficient [0]: 2*series[2] + series[1] == 0
1078
+
1079
+ sage: # needs sage.modules
1080
+ sage: A = L.undefined()
1081
+ sage: eq1 = diff(A, x) + diff(A, x, 2)
1082
+ sage: eq2 = A + diff(A, x) + diff(A, x, 2)
1083
+ sage: L.define_implicitly([A], [eq1, eq2], max_lookahead=2)
1084
+ sage: A
1085
+ O(x^7)
1086
+ """
1087
+ s = [a[0]._coeff_stream if isinstance(a, (tuple, list))
1088
+ else a._coeff_stream
1089
+ for a in series]
1090
+ ics = [a[1] if isinstance(a, (tuple, list))
1091
+ else []
1092
+ for a in series]
1093
+ eqs = [eq._coeff_stream for eq in equations]
1094
+ for f, ic in zip(s, ics):
1095
+ f.define_implicitly(s, ic, eqs,
1096
+ self.base_ring(),
1097
+ self._internal_poly_ring.base_ring(),
1098
+ self._terms_of_degree,
1099
+ max_lookahead=max_lookahead)
1100
+
1101
+ class options(GlobalOptions):
1102
+ r"""
1103
+ Set and display the options for lazy series.
1104
+
1105
+ If no parameters are set, then the function returns a copy of
1106
+ the options dictionary.
1107
+
1108
+ The ``options`` to lazy series can be accessed as using
1109
+ :class:`LazySeriesRing.options`.
1110
+
1111
+ @OPTIONS@
1112
+
1113
+ EXAMPLES::
1114
+
1115
+ sage: LLS.<z> = LazyLaurentSeriesRing(QQ)
1116
+ sage: LLS.options
1117
+ Current options for lazy series rings
1118
+ - constant_length: 3
1119
+ - display_length: 7
1120
+ - halting_precision: None
1121
+ - secure: False
1122
+
1123
+ sage: LLS.options.display_length
1124
+ 7
1125
+ sage: f = 1 / (1 + z)
1126
+ sage: f
1127
+ 1 - z + z^2 - z^3 + z^4 - z^5 + z^6 + O(z^7)
1128
+ sage: LLS.options.display_length = 10
1129
+ sage: f
1130
+ 1 - z + z^2 - z^3 + z^4 - z^5 + z^6 - z^7 + z^8 - z^9 + O(z^10)
1131
+ sage: g = LLS(lambda n: n^2, valuation=-2, degree=5, constant=42)
1132
+ sage: g
1133
+ 4*z^-2 + z^-1 + z + 4*z^2 + 9*z^3 + 16*z^4 + 42*z^5 + 42*z^6 + 42*z^7 + O(z^8)
1134
+ sage: h = 1 / (1 - z) # This is exact
1135
+ sage: h
1136
+ 1 + z + z^2 + O(z^3)
1137
+ sage: LLS.options.constant_length = 1
1138
+ sage: g
1139
+ 4*z^-2 + z^-1 + z + 4*z^2 + 9*z^3 + 16*z^4 + 42*z^5 + O(z^6)
1140
+ sage: h
1141
+ 1 + O(z)
1142
+ sage: LazyLaurentSeriesRing.options._reset()
1143
+ sage: LazyLaurentSeriesRing.options.display_length
1144
+ 7
1145
+ """
1146
+ NAME = 'lazy series rings'
1147
+ module = 'sage.rings.lazy_series_ring'
1148
+ display_length = dict(default=7,
1149
+ description='the number of coefficients to display from the valuation',
1150
+ checker=lambda x: x in ZZ and x > 0)
1151
+ constant_length = dict(default=3,
1152
+ description='the number of coefficients to display for nonzero constant series',
1153
+ checker=lambda x: x in ZZ and x > 0)
1154
+ halting_precision = dict(default=None,
1155
+ description='the number of coefficients, beginning with the approximate valuation, to check in equality tests',
1156
+ checker=lambda x: x is None or x in ZZ and x > 0)
1157
+ secure = dict(default=False,
1158
+ description='whether to raise an error when a comparison is unknown',
1159
+ checker=lambda x: x is True or x is False)
1160
+
1161
+ @cached_method
1162
+ def one(self):
1163
+ r"""
1164
+ Return the constant series `1`.
1165
+
1166
+ EXAMPLES::
1167
+
1168
+ sage: L = LazyLaurentSeriesRing(ZZ, 'z')
1169
+ sage: L.one()
1170
+ 1
1171
+
1172
+ sage: L = LazyPowerSeriesRing(ZZ, 'z')
1173
+ sage: L.one()
1174
+ 1
1175
+
1176
+ sage: m = SymmetricFunctions(ZZ).m() # needs sage.combinat sage.modules
1177
+ sage: L = LazySymmetricFunctions(m) # needs sage.combinat sage.modules
1178
+ sage: L.one() # needs sage.combinat sage.modules
1179
+ m[]
1180
+ """
1181
+ R = self.base_ring()
1182
+ coeff_stream = Stream_exact([R.one()], constant=R.zero(), order=0)
1183
+ return self.element_class(self, coeff_stream)
1184
+
1185
+ @cached_method
1186
+ def zero(self):
1187
+ r"""
1188
+ Return the zero series.
1189
+
1190
+ EXAMPLES::
1191
+
1192
+ sage: L = LazyLaurentSeriesRing(ZZ, 'z')
1193
+ sage: L.zero()
1194
+ 0
1195
+
1196
+ sage: s = SymmetricFunctions(ZZ).s() # needs sage.combinat sage.modules
1197
+ sage: L = LazySymmetricFunctions(s) # needs sage.combinat sage.modules
1198
+ sage: L.zero() # needs sage.combinat sage.modules
1199
+ 0
1200
+
1201
+ sage: L = LazyDirichletSeriesRing(ZZ, 'z')
1202
+ sage: L.zero()
1203
+ 0
1204
+
1205
+ sage: L = LazyPowerSeriesRing(ZZ, 'z')
1206
+ sage: L.zero()
1207
+ 0
1208
+ """
1209
+ return self.element_class(self, Stream_zero())
1210
+
1211
+ def characteristic(self):
1212
+ """
1213
+ Return the characteristic of this lazy power series ring, which
1214
+ is the same as the characteristic of its base ring.
1215
+
1216
+ EXAMPLES::
1217
+
1218
+ sage: L.<t> = LazyLaurentSeriesRing(ZZ)
1219
+ sage: L.characteristic()
1220
+ 0
1221
+
1222
+ sage: R.<w> = LazyLaurentSeriesRing(GF(11)); R
1223
+ Lazy Laurent Series Ring in w over Finite Field of size 11
1224
+ sage: R.characteristic()
1225
+ 11
1226
+
1227
+ sage: R.<x, y> = LazyPowerSeriesRing(GF(7)); R
1228
+ Multivariate Lazy Taylor Series Ring in x, y over Finite Field of size 7
1229
+ sage: R.characteristic()
1230
+ 7
1231
+
1232
+ sage: L = LazyDirichletSeriesRing(ZZ, "s")
1233
+ sage: L.characteristic()
1234
+ 0
1235
+ """
1236
+ return self.base_ring().characteristic()
1237
+
1238
+ def _coerce_map_from_(self, S):
1239
+ """
1240
+ Return ``True`` if a coercion from ``S`` exists.
1241
+
1242
+ EXAMPLES::
1243
+
1244
+ sage: L = LazyLaurentSeriesRing(GF(2), 'z')
1245
+ sage: L.has_coerce_map_from(ZZ)
1246
+ True
1247
+ sage: L.has_coerce_map_from(GF(2))
1248
+ True
1249
+ sage: R = LazyPowerSeriesRing(ZZ, 'z')
1250
+ sage: L.has_coerce_map_from(R)
1251
+ True
1252
+
1253
+ sage: L = LazyLaurentSeriesRing(QQ, 'z')
1254
+ sage: R = LazyPowerSeriesRing(QQ, 'z')
1255
+ sage: L.has_coerce_map_from(R)
1256
+ True
1257
+ sage: R = LazyPowerSeriesRing(ZZ, 'z')
1258
+ sage: L.has_coerce_map_from(R)
1259
+ True
1260
+ sage: R = LazyPowerSeriesRing(ZZ['t'], 'z')
1261
+ sage: L.has_coerce_map_from(R)
1262
+ False
1263
+
1264
+ sage: L = LazyPowerSeriesRing(GF(2), 'z')
1265
+ sage: L.has_coerce_map_from(ZZ)
1266
+ True
1267
+ sage: L.has_coerce_map_from(GF(2))
1268
+ True
1269
+
1270
+ sage: # needs sage.combinat sage.modules
1271
+ sage: s = SymmetricFunctions(GF(2)).s()
1272
+ sage: L = LazySymmetricFunctions(s)
1273
+ sage: L.has_coerce_map_from(ZZ)
1274
+ True
1275
+ sage: L.has_coerce_map_from(GF(2))
1276
+ True
1277
+ """
1278
+ if self.base_ring().has_coerce_map_from(S):
1279
+ return True
1280
+
1281
+ R = self._laurent_poly_ring
1282
+ if R.has_coerce_map_from(S):
1283
+ return True
1284
+
1285
+ if (isinstance(S, LazySeriesRing)
1286
+ and self._laurent_poly_ring.has_coerce_map_from(S._laurent_poly_ring)):
1287
+ return True
1288
+
1289
+ return None
1290
+
1291
+ def _coerce_map_from_base_ring(self):
1292
+ """
1293
+ Return a coercion map from the base ring of ``self``.
1294
+
1295
+ EXAMPLES::
1296
+
1297
+ sage: L = LazyLaurentSeriesRing(QQ, 'z')
1298
+ sage: phi = L._coerce_map_from_base_ring()
1299
+ sage: phi(2)
1300
+ 2
1301
+ sage: phi(2, valuation=-2)
1302
+ 2*z^-2
1303
+ sage: phi(2, valuation=-2, constant=3, degree=1)
1304
+ 2*z^-2 + 3*z + 3*z^2 + 3*z^3 + O(z^4)
1305
+
1306
+ sage: L = LazyDirichletSeriesRing(QQ, 'z')
1307
+ sage: phi = L._coerce_map_from_base_ring()
1308
+ sage: m = phi(2)
1309
+ sage: m # needs sage.symbolic
1310
+ 2
1311
+ sage: m = phi(2, valuation=2)
1312
+ sage: m # needs sage.symbolic
1313
+ 2/2^z
1314
+ sage: m = phi(2, valuation=2, constant=4)
1315
+ sage: m # needs sage.symbolic
1316
+ 2/2^z + 4/3^z + 4/4^z + 4/5^z + O(1/(6^z))
1317
+ """
1318
+ # Return a DefaultConvertMap_unique; this can pass additional
1319
+ # arguments to _element_constructor_, unlike the map returned
1320
+ # by UnitalAlgebras.ParentMethods._coerce_map_from_base_ring.
1321
+ return self._generic_coerce_map(self.base_ring())
1322
+
1323
+ def is_sparse(self):
1324
+ """
1325
+ Return whether ``self`` is sparse or not.
1326
+
1327
+ EXAMPLES::
1328
+
1329
+ sage: L = LazyLaurentSeriesRing(ZZ, 'z', sparse=False)
1330
+ sage: L.is_sparse()
1331
+ False
1332
+
1333
+ sage: L = LazyLaurentSeriesRing(ZZ, 'z', sparse=True)
1334
+ sage: L.is_sparse()
1335
+ True
1336
+ """
1337
+ return self._sparse
1338
+
1339
+ def is_exact(self):
1340
+ """
1341
+ Return if ``self`` is exact or not.
1342
+
1343
+ EXAMPLES::
1344
+
1345
+ sage: L = LazyLaurentSeriesRing(ZZ, 'z')
1346
+ sage: L.is_exact()
1347
+ True
1348
+ sage: L = LazyLaurentSeriesRing(RR, 'z')
1349
+ sage: L.is_exact()
1350
+ False
1351
+ """
1352
+ return self.base_ring().is_exact()
1353
+
1354
+ def prod(self, f, a=None, b=infinity, add_one=False):
1355
+ r"""
1356
+ The product of elements of ``self``.
1357
+
1358
+ INPUT:
1359
+
1360
+ - ``f`` -- list (or iterable) of elements of ``self``
1361
+ - ``a``, ``b`` -- optional arguments
1362
+ - ``add_one`` -- (default: ``False``) if ``True``, then converts a
1363
+ lazy series `p_i` from ``args`` into `1 + p_i` for the product
1364
+
1365
+ If ``a`` and ``b`` are both integers, then this returns the product
1366
+ `\prod_{i=a}^b f(i)`, where `f(i) = p_i` if ``add_one=False`` or
1367
+ `f(i) = 1 + p_i` otherwise. If ``b`` is not specified, then we consider
1368
+ `b = \infty`. Note this corresponds to the Python ``range(a, b+1)``.
1369
+
1370
+ If `a` is any other iterable, then this returns the product
1371
+ `\prod_{i \in a} f(i)`, where `f(i) = p_i` if ``add_one=False`` or
1372
+ `f(i) = 1 + p_i`.
1373
+
1374
+ .. NOTE::
1375
+
1376
+ For infinite products, it is faster to use ``add_one=True`` since
1377
+ the implementation is based on `p_i` in `\prod_i (1 + p_i)`.
1378
+
1379
+ .. WARNING::
1380
+
1381
+ When ``f`` is an infinite generator, then the first argument
1382
+ ``a`` must be ``True``. Otherwise this will loop forever.
1383
+
1384
+ .. WARNING::
1385
+
1386
+ For an *infinite* product of the form `\prod_i (1 + p_i)`,
1387
+ if `p_i = 0`, then this will loop forever.
1388
+
1389
+ EXAMPLES::
1390
+
1391
+ sage: L.<t> = LazyLaurentSeriesRing(QQ)
1392
+ sage: euler = L.prod(lambda n: 1 - t^n, PositiveIntegers())
1393
+ sage: euler
1394
+ 1 - t - t^2 + t^5 + O(t^7)
1395
+ sage: 1 / euler
1396
+ 1 + t + 2*t^2 + 3*t^3 + 5*t^4 + 7*t^5 + 11*t^6 + O(t^7)
1397
+ sage: euler - L.euler()
1398
+ O(t^7)
1399
+ sage: L.prod(lambda n: -t^n, 1, add_one=True)
1400
+ 1 - t - t^2 + t^5 + O(t^7)
1401
+
1402
+ sage: L.prod((1 - t^n for n in PositiveIntegers()), True)
1403
+ 1 - t - t^2 + t^5 + O(t^7)
1404
+ sage: L.prod((-t^n for n in PositiveIntegers()), True, add_one=True)
1405
+ 1 - t - t^2 + t^5 + O(t^7)
1406
+
1407
+ sage: L.prod((1 + t^(n-3) for n in PositiveIntegers()), True)
1408
+ 2*t^-3 + 4*t^-2 + 4*t^-1 + 4 + 6*t + 10*t^2 + 16*t^3 + O(t^4)
1409
+
1410
+ sage: L.prod(lambda n: 2 + t^n, -3, 5)
1411
+ 96*t^-6 + 240*t^-5 + 336*t^-4 + 840*t^-3 + 984*t^-2 + 1248*t^-1
1412
+ + 1980 + 1668*t + 1824*t^2 + 1872*t^3 + 1782*t^4 + 1710*t^5
1413
+ + 1314*t^6 + 1122*t^7 + 858*t^8 + 711*t^9 + 438*t^10 + 282*t^11
1414
+ + 210*t^12 + 84*t^13 + 60*t^14 + 24*t^15
1415
+ sage: L.prod(lambda n: t^n / (1 + abs(n)), -2, 2, add_one=True)
1416
+ 1/3*t^-3 + 5/6*t^-2 + 13/9*t^-1 + 25/9 + 13/9*t + 5/6*t^2 + 1/3*t^3
1417
+ sage: L.prod(lambda n: t^-2 + t^n / n, -4, -2)
1418
+ 1/24*t^-9 - 1/8*t^-8 - 1/6*t^-7 + 1/2*t^-6
1419
+
1420
+ sage: # needs sage.libs.pari sage.symbolic
1421
+ sage: D = LazyDirichletSeriesRing(QQ, "s")
1422
+ sage: D.prod(lambda p: (1+D(1, valuation=p)).inverse(), Primes())
1423
+ 1 - 1/(2^s) - 1/(3^s) + 1/(4^s) - 1/(5^s) + 1/(6^s) - 1/(7^s) + O(1/(8^s))
1424
+ sage: D.prod(lambda p: D(1, valuation=p), Primes(), add_one=True)
1425
+ 1 + 1/(2^s) + 1/(3^s) + 1/(5^s) + 1/(6^s) + 1/(7^s) + O(1/(8^s))
1426
+ """
1427
+ if a is None:
1428
+ if add_one:
1429
+ return super().prod(self.one() + g for g in f)
1430
+ return super().prod(f)
1431
+
1432
+ if a is True:
1433
+ it = f
1434
+ elif a in ZZ:
1435
+ if b != infinity:
1436
+ if add_one:
1437
+ return super().prod(self.one() + f(i) for i in range(a, b+1))
1438
+ return super().prod(f(i) for i in range(a, b+1))
1439
+ from sage.sets.non_negative_integers import NonNegativeIntegers
1440
+ it = (f(i+a) for i in NonNegativeIntegers())
1441
+ else:
1442
+ it = (f(i) for i in a)
1443
+
1444
+ # NOTE: We must have a new variable name for each new iterator
1445
+ if not add_one:
1446
+ data = (g - self.one() for g in it)
1447
+ else:
1448
+ data = it
1449
+
1450
+ from sage.data_structures.stream import Stream_infinite_product
1451
+ coeff_stream = Stream_infinite_product(data)
1452
+ return self.element_class(self, coeff_stream)
1453
+
1454
+ def sum(self, f, a=None, b=infinity):
1455
+ r"""
1456
+ The sum of elements of ``self``.
1457
+
1458
+ INPUT:
1459
+
1460
+ - ``f`` -- list (or iterable or function) of elements of ``self``
1461
+ - ``a``, ``b`` -- optional arguments
1462
+
1463
+ If ``a`` and ``b`` are both integers, then this returns the sum
1464
+ `\sum_{i=a}^b f(i)`. If ``b`` is not specified, then we consider
1465
+ `b = \infty`. Note this corresponds to the Python ``range(a, b+1)``.
1466
+
1467
+ If `a` is any other iterable, then this returns the sum
1468
+ `\sum{i \in a} f(i)`.
1469
+
1470
+ .. WARNING::
1471
+
1472
+ When ``f`` is an infinite generator, then the first argument
1473
+ ``a`` must be ``True``. Otherwise this will loop forever.
1474
+
1475
+ .. WARNING::
1476
+
1477
+ For an *infinite* sum of the form `\sum_i s_i`,
1478
+ if `s_i = 0`, then this will loop forever.
1479
+
1480
+ EXAMPLES::
1481
+
1482
+ sage: L.<t> = LazyLaurentSeriesRing(QQ)
1483
+ sage: L.sum(lambda n: t^n / (n+1), PositiveIntegers())
1484
+ 1/2*t + 1/3*t^2 + 1/4*t^3 + 1/5*t^4 + 1/6*t^5 + 1/7*t^6 + 1/8*t^7 + O(t^8)
1485
+
1486
+ sage: L.<z> = LazyPowerSeriesRing(QQ)
1487
+ sage: T = L.undefined(1)
1488
+ sage: D = L.undefined(0)
1489
+ sage: H = L.sum(lambda k: T(z^k)/k, 2)
1490
+ sage: T.define(z*exp(T)*D)
1491
+ sage: D.define(exp(H))
1492
+ sage: T
1493
+ z + z^2 + 2*z^3 + 4*z^4 + 9*z^5 + 20*z^6 + 48*z^7 + O(z^8)
1494
+ sage: D
1495
+ 1 + 1/2*z^2 + 1/3*z^3 + 7/8*z^4 + 11/30*z^5 + 281/144*z^6 + O(z^7)
1496
+
1497
+ We verify the Rogers-Ramanujan identities up to degree 100::
1498
+
1499
+ sage: L.<q> = LazyPowerSeriesRing(QQ)
1500
+ sage: Gpi = L.prod(lambda k: -q^(1+5*k), 0, oo, add_one=True)
1501
+ sage: Gpi *= L.prod(lambda k: -q^(4+5*k), 0, oo, add_one=True)
1502
+ sage: Gp = 1 / Gpi
1503
+ sage: G = L.sum(lambda n: q^(n^2) / prod(1 - q^(k+1) for k in range(n)), 0, oo)
1504
+ sage: G - Gp
1505
+ O(q^7)
1506
+ sage: all(G[k] == Gp[k] for k in range(100))
1507
+ True
1508
+
1509
+ sage: Hpi = L.prod(lambda k: -q^(2+5*k), 0, oo, add_one=True)
1510
+ sage: Hpi *= L.prod(lambda k: -q^(3+5*k), 0, oo, add_one=True)
1511
+ sage: Hp = 1 / Hpi
1512
+ sage: H = L.sum(lambda n: q^(n^2+n) / prod(1 - q^(k+1) for k in range(n)), 0, oo)
1513
+ sage: H - Hp
1514
+ O(q^7)
1515
+ sage: all(H[k] == Hp[k] for k in range(100))
1516
+ True
1517
+
1518
+ ::
1519
+
1520
+ sage: # needs sage.libs.pari sage.symbolic
1521
+ sage: D = LazyDirichletSeriesRing(QQ, "s")
1522
+ sage: D.sum(lambda p: D(1, valuation=p), Primes())
1523
+ 1/(2^s) + 1/(3^s) + 1/(5^s) + 1/(7^s) + O(1/(9^s))
1524
+ """
1525
+ if a is None:
1526
+ return super().sum(f)
1527
+
1528
+ if a is True:
1529
+ it = f
1530
+ elif a in ZZ:
1531
+ if b != infinity:
1532
+ return super().sum(f(i) for i in range(a, b+1))
1533
+ from sage.sets.non_negative_integers import NonNegativeIntegers
1534
+ it = (f(i+a) for i in NonNegativeIntegers())
1535
+ else:
1536
+ it = (f(i) for i in a)
1537
+
1538
+ from sage.data_structures.stream import Stream_infinite_sum
1539
+ coeff_stream = Stream_infinite_sum(it)
1540
+ return self.element_class(self, coeff_stream)
1541
+
1542
+ def _test_invert(self, **options):
1543
+ """
1544
+ Test multiplicative inversion of elements of ``self``.
1545
+
1546
+ INPUT:
1547
+
1548
+ - ``options`` -- any keyword arguments accepted by :meth:`_tester`
1549
+
1550
+ EXAMPLES::
1551
+
1552
+ sage: LazyLaurentSeriesRing.options.halting_precision(5)
1553
+ sage: L = LazyLaurentSeriesRing(QQ, 'z')
1554
+ sage: L._test_invert()
1555
+ sage: LazyLaurentSeriesRing.options._reset() # reset the options
1556
+
1557
+ .. SEEALSO::
1558
+
1559
+ :class:`TestSuite`
1560
+ """
1561
+ tester = self._tester(**options)
1562
+
1563
+ elements = tester.some_elements()
1564
+ for x in elements:
1565
+ # because of laziness, creating the inverse of x should
1566
+ # always succeed except if the series is 'exact'
1567
+ if not x.is_unit():
1568
+ continue
1569
+ y = ~x
1570
+ e = y * x
1571
+ tester.assertFalse(x.is_zero(), "zero should not be invertible")
1572
+ tester.assertTrue(e.is_one(), "an element (%s) times its inverse should be 1" % x)
1573
+ tester.assertEqual(y.valuation(), -x.valuation(), "the valuation of the inverse should be the negative of the valuation of the element (%s)" % x)
1574
+
1575
+ def _test_div(self, **options):
1576
+ r"""
1577
+ Test division of elements of this ring.
1578
+
1579
+ INPUT:
1580
+
1581
+ - ``options`` -- any keyword arguments accepted by :meth:`_tester`
1582
+
1583
+ EXAMPLES::
1584
+
1585
+ sage: LazyLaurentSeriesRing.options.halting_precision(5)
1586
+ sage: L = LazyLaurentSeriesRing(QQ, 'z')
1587
+ sage: L._test_div()
1588
+ sage: LazyLaurentSeriesRing.options._reset() # reset the options
1589
+
1590
+ .. SEEALSO::
1591
+
1592
+ :class:`TestSuite`
1593
+ """
1594
+ from sage.misc.misc import some_tuples
1595
+ tester = self._tester(**options)
1596
+
1597
+ elements = list(tester.some_elements())
1598
+ for x, y in some_tuples(elements, 2, tester._max_runs):
1599
+ # because of laziness, creating the inverse of x should
1600
+ # always succeed except if the series is 'exact'
1601
+ if not y.is_unit():
1602
+ continue
1603
+ z = x / y
1604
+ xx = z * y
1605
+ try:
1606
+ v_z = z.valuation()
1607
+ except Exception as error:
1608
+ raise ValueError("could not compute the valuation of the quotient (%s)/(%s): %s" % (x, y, error))
1609
+ else:
1610
+ v_x = x.valuation()
1611
+ v_y = y.valuation()
1612
+ tester.assertEqual(v_z, v_x - v_y, "the valuation of the quotient should be the difference of the valuations of the elements (%s and %s)" % (x, y))
1613
+ tester.assertEqual(xx, x, "the element (%s) should be the quotient times the divisor (%s)" % (x, y))
1614
+
1615
+ def _test_revert(self, **options):
1616
+ """
1617
+ Test compositional inverse of elements of this ring.
1618
+
1619
+ INPUT:
1620
+
1621
+ - ``options`` -- any keyword arguments accepted by :meth:`_tester`
1622
+
1623
+ EXAMPLES::
1624
+
1625
+ sage: LazyLaurentSeriesRing.options.halting_precision(5)
1626
+ sage: L = LazyLaurentSeriesRing(QQ, 'z')
1627
+ sage: L._test_revert()
1628
+ sage: LazyLaurentSeriesRing.options._reset()
1629
+
1630
+ .. SEEALSO::
1631
+
1632
+ :class:`TestSuite`
1633
+ """
1634
+ if not hasattr(self.element_class, "revert") or self._arity != 1:
1635
+ return
1636
+ tester = self._tester(**options)
1637
+
1638
+ elements = tester.some_elements()
1639
+ count = 0
1640
+ for x in elements:
1641
+ # because of laziness, creating the compositional inverse
1642
+ # of x should always succeed, except if the series is
1643
+ # 'exact' or if it has negative valuation
1644
+ vx = x.valuation()
1645
+ if (vx != 1
1646
+ and not (isinstance(x._coeff_stream, Stream_exact)
1647
+ and ((vx == 0
1648
+ and x._coeff_stream._degree == 2
1649
+ and not x._coeff_stream._constant)
1650
+ or (vx == -1
1651
+ and x._coeff_stream._degree == 0
1652
+ and not x._coeff_stream._constant)))):
1653
+ continue
1654
+ try:
1655
+ y = x.revert()
1656
+ except Exception as error:
1657
+ raise AssertionError("compositional inverse of %s should exist: %s" % (x, error))
1658
+ try:
1659
+ vy = y.valuation()
1660
+ _ = y[vy]
1661
+ except NotImplementedError:
1662
+ pass
1663
+ except (ValueError, TypeError):
1664
+ tester.assertFalse(vx == 1 and x[vx].is_unit(),
1665
+ ("the series %s should be reversible "
1666
+ "- its valuation is one and its leading coefficient is a unit") % x)
1667
+ else:
1668
+ count += 1
1669
+ e1 = y(x)
1670
+ e2 = x(y)
1671
+ tester.assertEqual(e1, e2, "y(x) and x(y) differ for x = %s and y = %s" % (x, y))
1672
+ # tester.assertEqual(e1, self.gen())
1673
+ # we want to test at least 2 elements
1674
+ tester.assertGreater(count, 1, msg="only %s elements in %s.some_elements() have a compositional inverse" % (count, self))
1675
+
1676
+
1677
+ class LazyLaurentSeriesRing(LazySeriesRing):
1678
+ r"""
1679
+ The ring of lazy Laurent series.
1680
+
1681
+ The ring of Laurent series over a ring with the usual arithmetic
1682
+ where the coefficients are computed lazily.
1683
+
1684
+ INPUT:
1685
+
1686
+ - ``base_ring`` -- base ring
1687
+ - ``names`` -- name of the generator
1688
+ - ``sparse`` -- boolean (default: ``True``); whether the implementation of
1689
+ the series is sparse or not
1690
+
1691
+ EXAMPLES::
1692
+
1693
+ sage: L.<z> = LazyLaurentSeriesRing(QQ)
1694
+ sage: 1 / (1 - z)
1695
+ 1 + z + z^2 + O(z^3)
1696
+ sage: 1 / (1 - z) == 1 / (1 - z)
1697
+ True
1698
+ sage: L in Fields
1699
+ True
1700
+
1701
+ Lazy Laurent series ring over a finite field::
1702
+
1703
+ sage: # needs sage.rings.finite_rings
1704
+ sage: L.<z> = LazyLaurentSeriesRing(GF(3)); L
1705
+ Lazy Laurent Series Ring in z over Finite Field of size 3
1706
+ sage: e = 1 / (1 + z)
1707
+ sage: e.coefficient(100)
1708
+ 1
1709
+ sage: e.coefficient(100).parent()
1710
+ Finite Field of size 3
1711
+
1712
+ Series can be defined by specifying a coefficient function
1713
+ and a valuation::
1714
+
1715
+ sage: R.<x,y> = QQ[]
1716
+ sage: L.<z> = LazyLaurentSeriesRing(R)
1717
+ sage: def coeff(n):
1718
+ ....: if n < 0:
1719
+ ....: return -2 + n
1720
+ ....: if n == 0:
1721
+ ....: return 6
1722
+ ....: return x + y^n
1723
+ sage: f = L(coeff, valuation=-5)
1724
+ sage: f
1725
+ -7*z^-5 - 6*z^-4 - 5*z^-3 - 4*z^-2 - 3*z^-1 + 6 + (x + y)*z + O(z^2)
1726
+ sage: 1 / (1 - f)
1727
+ 1/7*z^5 - 6/49*z^6 + 1/343*z^7 + 8/2401*z^8 + 64/16807*z^9
1728
+ + 17319/117649*z^10 + (1/49*x + 1/49*y - 180781/823543)*z^11 + O(z^12)
1729
+ sage: L(coeff, valuation=-3, degree=3, constant=x)
1730
+ -5*z^-3 - 4*z^-2 - 3*z^-1 + 6 + (x + y)*z + (y^2 + x)*z^2
1731
+ + x*z^3 + x*z^4 + x*z^5 + O(z^6)
1732
+
1733
+ We can also specify a polynomial or the initial coefficients.
1734
+ Additionally, we may specify that all coefficients are equal to a
1735
+ given constant, beginning at a given degree::
1736
+
1737
+ sage: L([1, x, y, 0, x+y])
1738
+ 1 + x*z + y*z^2 + (x + y)*z^4
1739
+ sage: L([1, x, y, 0, x+y], constant=2)
1740
+ 1 + x*z + y*z^2 + (x + y)*z^4 + 2*z^5 + 2*z^6 + 2*z^7 + O(z^8)
1741
+ sage: L([1, x, y, 0, x+y], degree=7, constant=2)
1742
+ 1 + x*z + y*z^2 + (x + y)*z^4 + 2*z^7 + 2*z^8 + 2*z^9 + O(z^10)
1743
+ sage: L([1, x, y, 0, x+y], valuation=-2)
1744
+ z^-2 + x*z^-1 + y + (x + y)*z^2
1745
+ sage: L([1, x, y, 0, x+y], valuation=-2, constant=3)
1746
+ z^-2 + x*z^-1 + y + (x + y)*z^2 + 3*z^3 + 3*z^4 + 3*z^5 + O(z^6)
1747
+ sage: L([1, x, y, 0, x+y], valuation=-2, degree=4, constant=3)
1748
+ z^-2 + x*z^-1 + y + (x + y)*z^2 + 3*z^4 + 3*z^5 + 3*z^6 + O(z^7)
1749
+
1750
+ Some additional examples over the integer ring::
1751
+
1752
+ sage: L.<z> = LazyLaurentSeriesRing(ZZ)
1753
+ sage: L in Fields
1754
+ False
1755
+ sage: 1 / (1 - 2*z)^3
1756
+ 1 + 6*z + 24*z^2 + 80*z^3 + 240*z^4 + 672*z^5 + 1792*z^6 + O(z^7)
1757
+
1758
+ sage: R.<x> = LaurentPolynomialRing(ZZ)
1759
+ sage: L(x^-2 + 3 + x)
1760
+ z^-2 + 3 + z
1761
+ sage: L(x^-2 + 3 + x, valuation=-5, constant=2)
1762
+ z^-5 + 3*z^-3 + z^-2 + 2*z^-1 + 2 + 2*z + O(z^2)
1763
+ sage: L(x^-2 + 3 + x, valuation=-5, degree=0, constant=2)
1764
+ z^-5 + 3*z^-3 + z^-2 + 2 + 2*z + 2*z^2 + O(z^3)
1765
+
1766
+ We can truncate a series, shift its coefficients, or replace all
1767
+ coefficients beginning with a given degree by a constant::
1768
+
1769
+ sage: f = 1 / (z + z^2)
1770
+ sage: f
1771
+ z^-1 - 1 + z - z^2 + z^3 - z^4 + z^5 + O(z^6)
1772
+ sage: L(f, valuation=2)
1773
+ z^2 - z^3 + z^4 - z^5 + z^6 - z^7 + z^8 + O(z^9)
1774
+ sage: L(f, degree=3)
1775
+ z^-1 - 1 + z - z^2
1776
+ sage: L(f, degree=3, constant=2)
1777
+ z^-1 - 1 + z - z^2 + 2*z^3 + 2*z^4 + 2*z^5 + O(z^6)
1778
+ sage: L(f, valuation=1, degree=4)
1779
+ z - z^2 + z^3
1780
+ sage: L(f, valuation=1, degree=4, constant=5)
1781
+ z - z^2 + z^3 + 5*z^4 + 5*z^5 + 5*z^6 + O(z^7)
1782
+
1783
+ Power series can be defined recursively (see
1784
+ :meth:`sage.rings.lazy_series.LazyModuleElement.define` for
1785
+ more examples)::
1786
+
1787
+ sage: L.<z> = LazyLaurentSeriesRing(ZZ)
1788
+ sage: s = L.undefined(valuation=0)
1789
+ sage: s.define(1 + z*s^2)
1790
+ sage: s
1791
+ 1 + z + 2*z^2 + 5*z^3 + 14*z^4 + 42*z^5 + 132*z^6 + O(z^7)
1792
+
1793
+ By default, any two series ``f`` and ``g`` that are not known to
1794
+ be equal are considered to be different::
1795
+
1796
+ sage: f = L(lambda n: 0, valuation=0)
1797
+ sage: f == 0
1798
+ False
1799
+
1800
+ sage: f = L(constant=1, valuation=0).derivative(); f
1801
+ 1 + 2*z + 3*z^2 + 4*z^3 + 5*z^4 + 6*z^5 + 7*z^6 + O(z^7)
1802
+ sage: g = L(lambda n: (n+1), valuation=0); g
1803
+ 1 + 2*z + 3*z^2 + 4*z^3 + 5*z^4 + 6*z^5 + 7*z^6 + O(z^7)
1804
+ sage: f == g
1805
+ False
1806
+
1807
+ .. WARNING::
1808
+
1809
+ We have imposed that ``(f == g) == not (f != g)``, and so
1810
+ ``f != g`` returning ``True`` might not mean that the two
1811
+ series are actually different::
1812
+
1813
+ sage: f = L(lambda n: 0, valuation=0)
1814
+ sage: g = L.zero()
1815
+ sage: f != g
1816
+ True
1817
+
1818
+ This can be verified by :meth:`~sage.rings.lazy_series.is_nonzero()`,
1819
+ which only returns ``True`` if the series is known to be nonzero::
1820
+
1821
+ sage: (f - g).is_nonzero()
1822
+ False
1823
+
1824
+ The implementation of the ring can be either be a sparse or a dense one.
1825
+ The default is a sparse implementation::
1826
+
1827
+ sage: L.<z> = LazyLaurentSeriesRing(ZZ)
1828
+ sage: L.is_sparse()
1829
+ True
1830
+ sage: L.<z> = LazyLaurentSeriesRing(ZZ, sparse=False)
1831
+ sage: L.is_sparse()
1832
+ False
1833
+
1834
+ We additionally provide two other methods of performing comparisons.
1835
+ The first is raising a :exc:`ValueError` and the second uses a check
1836
+ up to a (user set) finite precision. These behaviors are set using the
1837
+ options ``secure`` and ``halting_precision``. In particular,
1838
+ this applies to series that are not specified by a finite number
1839
+ of initial coefficients and a constant for the remaining coefficients.
1840
+ Equality checking will depend on the coefficients which have
1841
+ already been computed. If this information is not enough to
1842
+ check that two series are different, then if ``L.options.secure``
1843
+ is set to ``True``, then we raise a :exc:`ValueError`::
1844
+
1845
+ sage: L.options.secure = True
1846
+ sage: f = 1 / (z + z^2); f
1847
+ z^-1 - 1 + z - z^2 + z^3 - z^4 + z^5 + O(z^6)
1848
+ sage: f2 = f * 2 # currently no coefficients computed
1849
+ sage: f3 = f * 3 # currently no coefficients computed
1850
+ sage: f2 == f3
1851
+ Traceback (most recent call last):
1852
+ ...
1853
+ ValueError: undecidable
1854
+ sage: f2 # computes some of the coefficients of f2
1855
+ 2*z^-1 - 2 + 2*z - 2*z^2 + 2*z^3 - 2*z^4 + 2*z^5 + O(z^6)
1856
+ sage: f3 # computes some of the coefficients of f3
1857
+ 3*z^-1 - 3 + 3*z - 3*z^2 + 3*z^3 - 3*z^4 + 3*z^5 + O(z^6)
1858
+ sage: f2 == f3
1859
+ False
1860
+ sage: f2a = f + f
1861
+ sage: f2 == f2a
1862
+ Traceback (most recent call last):
1863
+ ...
1864
+ ValueError: undecidable
1865
+ sage: zf = L(lambda n: 0, valuation=0)
1866
+ sage: zf == 0
1867
+ Traceback (most recent call last):
1868
+ ...
1869
+ ValueError: undecidable
1870
+
1871
+ For boolean checks, an error is raised when it is not known to be nonzero::
1872
+
1873
+ sage: bool(zf)
1874
+ Traceback (most recent call last):
1875
+ ...
1876
+ ValueError: undecidable
1877
+
1878
+ If the halting precision is set to a finite number `p` (for unlimited
1879
+ precision, it is set to ``None``), then it will check up to `p` values
1880
+ from the current position::
1881
+
1882
+ sage: L.options.halting_precision = 20
1883
+ sage: f2 = f * 2 # currently no coefficients computed
1884
+ sage: f3 = f * 3 # currently no coefficients computed
1885
+ sage: f2 == f3
1886
+ False
1887
+ sage: f2a = f + f
1888
+ sage: f2 == f2a
1889
+ True
1890
+ sage: zf = L(lambda n: 0, valuation=0)
1891
+ sage: zf == 0
1892
+ True
1893
+
1894
+ TESTS:
1895
+
1896
+ We reset the options::
1897
+
1898
+ sage: L.options._reset()
1899
+ """
1900
+ Element = LazyLaurentSeries
1901
+
1902
+ # Follow the "generic" normalization
1903
+ __classcall_private__ = LazySeriesRing.__classcall_private__
1904
+
1905
+ def __init__(self, base_ring, names, sparse=True, category=None):
1906
+ """
1907
+ Initialize ``self``.
1908
+
1909
+ TESTS::
1910
+
1911
+ sage: LazyLaurentSeriesRing.options.halting_precision(12)
1912
+
1913
+ sage: L = LazyLaurentSeriesRing(ZZ, 't')
1914
+ sage: TestSuite(L).run()
1915
+ sage: L.category()
1916
+ Category of infinite commutative no zero divisors algebras over
1917
+ (Dedekind domains and euclidean domains
1918
+ and noetherian rings
1919
+ and infinite enumerated sets and metric spaces)
1920
+
1921
+ sage: L = LazyLaurentSeriesRing(QQ, 't')
1922
+ sage: TestSuite(L).run()
1923
+ sage: L.category()
1924
+ Join of Category of complete discrete valuation fields
1925
+ and Category of commutative algebras over (number fields and quotient fields and metric spaces)
1926
+ and Category of infinite sets
1927
+
1928
+ sage: L = LazyLaurentSeriesRing(ZZ['x, y'], 't')
1929
+ sage: TestSuite(L).run() # needs sage.libs.singular
1930
+ sage: L.category()
1931
+ Category of infinite commutative no zero divisors algebras over
1932
+ (unique factorization domains and algebras with basis over
1933
+ (Dedekind domains and euclidean domains
1934
+ and noetherian rings
1935
+ and infinite enumerated sets and metric spaces)
1936
+ and commutative algebras over
1937
+ (Dedekind domains and euclidean domains
1938
+ and noetherian rings
1939
+ and infinite enumerated sets and metric spaces)
1940
+ and infinite sets)
1941
+
1942
+ sage: L = LazyLaurentSeriesRing(GF(5), 't')
1943
+ sage: TestSuite(L).run()
1944
+
1945
+ sage: L = LazyLaurentSeriesRing(GF(5)['x'], 't')
1946
+ sage: TestSuite(L).run()
1947
+
1948
+ sage: L = LazyLaurentSeriesRing(GF(5)['x, y'], 't')
1949
+ sage: TestSuite(L).run() # needs sage.libs.singular
1950
+
1951
+ sage: L = LazyLaurentSeriesRing(Zmod(6), 't')
1952
+ sage: TestSuite(L).run(skip=['_test_revert'])
1953
+ sage: L.category()
1954
+ Category of infinite commutative algebras over
1955
+ (finite commutative rings and subquotients of monoids
1956
+ and quotients of semigroups and finite enumerated sets)
1957
+
1958
+ sage: E.<x,y> = ExteriorAlgebra(QQ) # needs sage.modules
1959
+ sage: L = LazyLaurentSeriesRing(E, 't') # not tested # needs sage.modules
1960
+
1961
+ sage: LazyLaurentSeriesRing.options._reset() # reset the options
1962
+ """
1963
+ self._sparse = sparse
1964
+ if len(names) != 1:
1965
+ raise ValueError("only univariate lazy Laurent series are implemented")
1966
+ self._arity = 1
1967
+ self._minimal_valuation = None
1968
+ self._laurent_poly_ring = LaurentPolynomialRing(base_ring, names, sparse=sparse)
1969
+ self._internal_poly_ring = self._laurent_poly_ring
1970
+
1971
+ category = Algebras(base_ring.category())
1972
+ if base_ring in Fields():
1973
+ category &= CompleteDiscreteValuationFields()
1974
+ elif base_ring in IntegralDomains():
1975
+ category &= IntegralDomains()
1976
+ elif "Commutative" in base_ring.category().axioms():
1977
+ category = category.Commutative()
1978
+
1979
+ if base_ring.is_zero():
1980
+ category = category.Finite()
1981
+ else:
1982
+ category = category.Infinite()
1983
+
1984
+ Parent.__init__(self, base=base_ring, names=names, category=category)
1985
+
1986
+ def _repr_(self):
1987
+ """
1988
+ Return a string representation of ``self``.
1989
+
1990
+ EXAMPLES::
1991
+
1992
+ sage: LazyLaurentSeriesRing(GF(2), 'z')
1993
+ Lazy Laurent Series Ring in z over Finite Field of size 2
1994
+ """
1995
+ return "Lazy Laurent Series Ring in {} over {}".format(self.variable_name(), self.base_ring())
1996
+
1997
+ def _latex_(self):
1998
+ r"""
1999
+ Return a latex representation of ``self``.
2000
+
2001
+ EXAMPLES::
2002
+
2003
+ sage: L = LazyLaurentSeriesRing(GF(2), 'z')
2004
+ sage: latex(L)
2005
+ \Bold{F}_{2} (\!(z)\!)
2006
+ """
2007
+ from sage.misc.latex import latex
2008
+ return latex(self.base_ring()) + r"(\!({})\!)".format(self.variable_name())
2009
+
2010
+ @cached_method
2011
+ def gen(self, n=0):
2012
+ r"""
2013
+ Return the ``n``-th generator of ``self``.
2014
+
2015
+ EXAMPLES::
2016
+
2017
+ sage: L = LazyLaurentSeriesRing(ZZ, 'z')
2018
+ sage: L.gen()
2019
+ z
2020
+ sage: L.gen(3)
2021
+ Traceback (most recent call last):
2022
+ ...
2023
+ IndexError: there is only one generator
2024
+ """
2025
+ if n != 0:
2026
+ raise IndexError("there is only one generator")
2027
+ R = self.base_ring()
2028
+ coeff_stream = Stream_exact([R.one()], constant=R.zero(), order=1)
2029
+ return self.element_class(self, coeff_stream)
2030
+
2031
+ def ngens(self):
2032
+ r"""
2033
+ Return the number of generators of ``self``.
2034
+
2035
+ This is always 1.
2036
+
2037
+ EXAMPLES::
2038
+
2039
+ sage: L.<z> = LazyLaurentSeriesRing(ZZ)
2040
+ sage: L.ngens()
2041
+ 1
2042
+ """
2043
+ return 1
2044
+
2045
+ @cached_method
2046
+ def gens(self) -> tuple:
2047
+ """
2048
+ Return the generators of ``self``.
2049
+
2050
+ EXAMPLES::
2051
+
2052
+ sage: L.<z> = LazyLaurentSeriesRing(ZZ)
2053
+ sage: L.gens()
2054
+ (z,)
2055
+ sage: 1/(1 - z)
2056
+ 1 + z + z^2 + O(z^3)
2057
+ """
2058
+ return tuple([self.gen(n) for n in range(self.ngens())])
2059
+
2060
+ def _an_element_(self):
2061
+ """
2062
+ Return a Laurent series in ``self``.
2063
+
2064
+ EXAMPLES::
2065
+
2066
+ sage: L = LazyLaurentSeriesRing(ZZ, 'z')
2067
+ sage: L.an_element()
2068
+ z^-2 + z^3 + z^4 + z^5 + O(z^6)
2069
+ """
2070
+ return self(self._laurent_poly_ring.an_element(),
2071
+ valuation=-2,
2072
+ degree=3,
2073
+ constant=self.base_ring().an_element())
2074
+
2075
+ def some_elements(self):
2076
+ """
2077
+ Return a list of elements of ``self``.
2078
+
2079
+ EXAMPLES::
2080
+
2081
+ sage: L = LazyLaurentSeriesRing(ZZ, 'z')
2082
+ sage: L.some_elements()[:7]
2083
+ [0, 1, z,
2084
+ -3*z^-4 + z^-3 - 12*z^-2 - 2*z^-1 - 10 - 8*z + z^2 + z^3,
2085
+ z^-2 + z^3 + z^4 + z^5 + O(z^6),
2086
+ -2*z^-3 - 2*z^-2 + 4*z^-1 + 11 - z - 34*z^2 - 31*z^3 + O(z^4),
2087
+ 4*z^-2 + z^-1 + z + 4*z^2 + 9*z^3 + 16*z^4 + O(z^5)]
2088
+
2089
+ sage: L = LazyLaurentSeriesRing(GF(2), 'z')
2090
+ sage: L.some_elements()[:7]
2091
+ [0, 1, z,
2092
+ z^-4 + z^-3 + z^2 + z^3,
2093
+ z^-2,
2094
+ 1 + z + z^3 + z^4 + z^6 + O(z^7),
2095
+ z^-1 + z + z^3 + O(z^5)]
2096
+
2097
+ sage: L = LazyLaurentSeriesRing(GF(3), 'z')
2098
+ sage: L.some_elements()[:7]
2099
+ [0, 1, z,
2100
+ z^-3 + z^-1 + 2 + z + z^2 + z^3,
2101
+ z^-2,
2102
+ z^-3 + z^-2 + z^-1 + 2 + 2*z + 2*z^2 + O(z^3),
2103
+ z^-2 + z^-1 + z + z^2 + z^4 + O(z^5)]
2104
+ """
2105
+ z = self.gen()
2106
+ elts = [self.zero(), self.one(), z, (z-3)*(z**-2+2+z)**2, self.an_element(),
2107
+ (1 - 2*z**-3)/(1 - z + 3*z**2),
2108
+ self(lambda n: n**2, valuation=-2),
2109
+ self(lambda n: n**2, valuation=1),
2110
+ self([3, 2, 1], valuation=1, constant=1)]
2111
+ return elts
2112
+
2113
+ def series(self, coefficient, valuation, degree=None, constant=None):
2114
+ r"""
2115
+ Return a lazy Laurent series.
2116
+
2117
+ INPUT:
2118
+
2119
+ - ``coefficient`` -- Python function that computes coefficients or a list
2120
+ - ``valuation`` -- integer; approximate valuation of the series
2121
+ - ``degree`` -- (optional) integer
2122
+ - ``constant`` -- (optional) an element of the base ring
2123
+
2124
+ Let the coefficient of index `i` mean the coefficient of the term
2125
+ of the series with exponent `i`.
2126
+
2127
+ Python function ``coefficient`` returns the value of the coefficient
2128
+ of index `i` from input `s` and `i` where `s` is the series itself.
2129
+
2130
+ Let ``valuation`` be `n`. All coefficients of index below `n` are zero.
2131
+ If ``constant`` is not specified, then the ``coefficient`` function is
2132
+ responsible to compute the values of all coefficients of index `\ge n`.
2133
+ If ``degree`` or ``constant`` is a pair `(c,m)`, then the ``coefficient``
2134
+ function is responsible to compute the values of all coefficients of
2135
+ index `\ge n` and `< m` and all the coefficients of index `\ge m`
2136
+ is the constant `c`.
2137
+
2138
+ EXAMPLES::
2139
+
2140
+ sage: L = LazyLaurentSeriesRing(ZZ, 'z')
2141
+ sage: L.series(lambda s, i: i, 5, (1,10))
2142
+ 5*z^5 + 6*z^6 + 7*z^7 + 8*z^8 + 9*z^9 + z^10 + z^11 + z^12 + O(z^13)
2143
+
2144
+ sage: def g(s, i):
2145
+ ....: if i < 0:
2146
+ ....: return 1
2147
+ ....: else:
2148
+ ....: return s.coefficient(i - 1) + i
2149
+ sage: e = L.series(g, -5); e
2150
+ z^-5 + z^-4 + z^-3 + z^-2 + z^-1 + 1 + 2*z + O(z^2)
2151
+ sage: f = e^-1; f
2152
+ z^5 - z^6 - z^11 + O(z^12)
2153
+ sage: f.coefficient(10)
2154
+ 0
2155
+ sage: f.coefficient(20)
2156
+ 9
2157
+ sage: f.coefficient(30)
2158
+ -219
2159
+
2160
+ Alternatively, the ``coefficient`` can be a list of elements of the
2161
+ base ring. Then these elements are read as coefficients of the terms of
2162
+ degrees starting from the ``valuation``. In this case, ``constant``
2163
+ may be just an element of the base ring instead of a tuple or can be
2164
+ simply omitted if it is zero. ::
2165
+
2166
+ sage: L = LazyLaurentSeriesRing(ZZ, 'z')
2167
+ sage: f = L.series([1,2,3,4], -5); f
2168
+ z^-5 + 2*z^-4 + 3*z^-3 + 4*z^-2
2169
+ sage: g = L.series([1,3,5,7,9], 5, constant=-1); g
2170
+ z^5 + 3*z^6 + 5*z^7 + 7*z^8 + 9*z^9 - z^10 - z^11 - z^12 + O(z^13)
2171
+ """
2172
+ if valuation is not None and valuation not in ZZ:
2173
+ raise ValueError("the valuation must be an integer")
2174
+
2175
+ if isinstance(constant, (list, tuple)):
2176
+ constant, degree = constant
2177
+ if isinstance(degree, (list, tuple)):
2178
+ constant, degree = degree
2179
+
2180
+ if constant is not None:
2181
+ constant = self.base_ring()(constant)
2182
+
2183
+ if isinstance(coefficient, (tuple, list)):
2184
+ if constant is None:
2185
+ constant = self.base_ring().zero()
2186
+ if degree is None:
2187
+ degree = valuation + len(coefficient)
2188
+ coeff_stream = Stream_exact(coefficient, order=valuation,
2189
+ constant=constant, degree=degree)
2190
+ return self.element_class(self, coeff_stream)
2191
+
2192
+ if degree is not None and valuation > degree and constant:
2193
+ raise ValueError('inappropriate valuation')
2194
+
2195
+ t = None
2196
+ t = self(lambda n: coefficient(t, n), valuation=valuation,
2197
+ constant=constant, degree=degree)
2198
+ return t
2199
+
2200
+ def _monomial(self, c, n):
2201
+ r"""
2202
+ Return the interpretation of the coefficient ``c`` at index ``n``.
2203
+
2204
+ EXAMPLES::
2205
+
2206
+ sage: L = LazyLaurentSeriesRing(ZZ, 'z')
2207
+ sage: L._monomial(1, 3)
2208
+ z^3
2209
+ sage: L._monomial(2, -4)
2210
+ 2*z^-4
2211
+ """
2212
+ return self._laurent_poly_ring(c).shift(n)
2213
+
2214
+ def _terms_of_degree(self, n, R):
2215
+ r"""
2216
+ Return the list consisting of a single element ``1`` in the given
2217
+ ring.
2218
+
2219
+ EXAMPLES::
2220
+
2221
+ sage: L = LazyLaurentSeriesRing(ZZ, 'z')
2222
+ sage: t = L._terms_of_degree(3, ZZ['x']); t
2223
+ [1]
2224
+ sage: t[0].parent()
2225
+ Univariate Polynomial Ring in x over Integer Ring
2226
+ """
2227
+ return [R.one()]
2228
+
2229
+ def uniformizer(self):
2230
+ """
2231
+ Return a uniformizer of ``self``..
2232
+
2233
+ EXAMPLES::
2234
+
2235
+ sage: L = LazyLaurentSeriesRing(QQ, 'z')
2236
+ sage: L.uniformizer()
2237
+ z
2238
+ """
2239
+ R = self.base_ring()
2240
+ if R not in Fields():
2241
+ raise TypeError("the base ring is not a field")
2242
+ return self.gen()
2243
+
2244
+ def residue_field(self):
2245
+ """
2246
+ Return the residue field of the ring of integers of ``self``.
2247
+
2248
+ EXAMPLES::
2249
+
2250
+ sage: L = LazyLaurentSeriesRing(QQ, 'z')
2251
+ sage: L.residue_field()
2252
+ Rational Field
2253
+ """
2254
+ R = self.base_ring()
2255
+ if R not in Fields():
2256
+ raise TypeError("the base ring is not a field")
2257
+ return R
2258
+
2259
+ def taylor(self, f):
2260
+ r"""
2261
+ Return the Taylor expansion around `0` of the function ``f``.
2262
+
2263
+ INPUT:
2264
+
2265
+ - ``f`` -- a function such that one of the following works:
2266
+
2267
+ * the substitution `f(z)`, where `z` is a generator of ``self``
2268
+ * `f` is a function of a single variable with no poles at `0`
2269
+ and has a ``derivative`` method
2270
+
2271
+ EXAMPLES::
2272
+
2273
+ sage: # needs sage.symbolic
2274
+ sage: L.<z> = LazyLaurentSeriesRing(QQ)
2275
+ sage: x = SR.var('x')
2276
+ sage: f(x) = (1 + x) / (1 - x^2)
2277
+ sage: L.taylor(f)
2278
+ 1 + z + z^2 + z^3 + z^4 + z^5 + z^6 + O(z^7)
2279
+
2280
+ For inputs as symbolic functions/expressions, the function must
2281
+ not have any poles at `0`::
2282
+
2283
+ sage: # needs sage.symbolic
2284
+ sage: f(x) = (1 + x^2) / sin(x^2)
2285
+ sage: L.taylor(f)
2286
+ <repr(...) failed: ValueError: power::eval(): division by zero>
2287
+ sage: def g(a): return (1 + a^2) / sin(a^2)
2288
+ sage: L.taylor(g)
2289
+ z^-2 + 1 + 1/6*z^2 + 1/6*z^4 + O(z^5)
2290
+ """
2291
+ try:
2292
+ return f(self.gen())
2293
+ except (ValueError, TypeError):
2294
+ pass
2295
+ stream = Stream_taylor(f, self.is_sparse())
2296
+ return self.element_class(self, stream)
2297
+
2298
+ # === special functions ===
2299
+
2300
+ def q_pochhammer(self, q=None):
2301
+ r"""
2302
+ Return the infinite ``q``-Pochhammer symbol `(a; q)_{\infty}`,
2303
+ where `a` is the variable of ``self``.
2304
+
2305
+ This is also one version of the quantum dilogarithm or
2306
+ the `q`-Exponential function.
2307
+
2308
+ INPUT:
2309
+
2310
+ - ``q`` -- (default: `q \in \QQ(q)`) the parameter `q`
2311
+
2312
+ EXAMPLES::
2313
+
2314
+ sage: q = ZZ['q'].fraction_field().gen()
2315
+ sage: L.<z> = LazyLaurentSeriesRing(q.parent())
2316
+ sage: qpoch = L.q_pochhammer(q)
2317
+ sage: qpoch
2318
+ 1
2319
+ + (-1/(-q + 1))*z
2320
+ + (q/(q^3 - q^2 - q + 1))*z^2
2321
+ + (-q^3/(-q^6 + q^5 + q^4 - q^2 - q + 1))*z^3
2322
+ + (q^6/(q^10 - q^9 - q^8 + 2*q^5 - q^2 - q + 1))*z^4
2323
+ + (-q^10/(-q^15 + q^14 + q^13 - q^10 - q^9 - q^8 + q^7 + q^6 + q^5 - q^2 - q + 1))*z^5
2324
+ + (q^15/(q^21 - q^20 - q^19 + q^16 + 2*q^14 - q^12 - q^11 - q^10 - q^9 + 2*q^7 + q^5 - q^2 - q + 1))*z^6
2325
+ + O(z^7)
2326
+
2327
+ We show that `(z; q)_n = \frac{(z; q)_{\infty}}{(q^n z; q)_{\infty}}`::
2328
+
2329
+ sage: qpoch / qpoch(q*z)
2330
+ 1 - z + O(z^7)
2331
+ sage: qpoch / qpoch(q^2*z)
2332
+ 1 + (-q - 1)*z + q*z^2 + O(z^7)
2333
+ sage: qpoch / qpoch(q^3*z)
2334
+ 1 + (-q^2 - q - 1)*z + (q^3 + q^2 + q)*z^2 - q^3*z^3 + O(z^7)
2335
+ sage: qpoch / qpoch(q^4*z)
2336
+ 1 + (-q^3 - q^2 - q - 1)*z + (q^5 + q^4 + 2*q^3 + q^2 + q)*z^2
2337
+ + (-q^6 - q^5 - q^4 - q^3)*z^3 + q^6*z^4 + O(z^7)
2338
+
2339
+ We can also construct part of Euler's function::
2340
+
2341
+ sage: M.<a> = LazyLaurentSeriesRing(QQ)
2342
+ sage: phi = sum(qpoch[i](q=a)*a^i for i in range(10))
2343
+ sage: phi[:20] == M.euler()[:20]
2344
+ True
2345
+
2346
+ TESTS::
2347
+
2348
+ sage: R = ZZ['q'].fraction_field()
2349
+ sage: q = R.gen()
2350
+ sage: L.<z> = LazyLaurentSeriesRing(LazyDirichletSeriesRing(R, "s"))
2351
+ sage: z.q_pochhammer(q) # needs sage.symbolic
2352
+ 1 + ((1/(q-1)))*z + ((q/(q^3-q^2-q+1)))*z^2 + ... + O(z^7)
2353
+
2354
+ REFERENCES:
2355
+
2356
+ - :wikipedia:`Q-Pochhammer_symbol`
2357
+ - :wikipedia:`Quantum_dilogarithm`
2358
+ - :wikipedia:`Q-exponential`
2359
+ """
2360
+ if q is None:
2361
+ q = ZZ['q'].fraction_field().gen()
2362
+ if q not in self.base_ring():
2363
+ raise ValueError("q must be in the base ring")
2364
+ from sage.arith.misc import binomial
2365
+ qP = q.parent()
2366
+ one = qP.one()
2367
+
2368
+ def coeff(n):
2369
+ return (-1)**n * q**binomial(n, 2) / qP.prod(one - q**i for i in range(1, n+1))
2370
+ return self(coefficients=coeff, valuation=0)
2371
+
2372
+ def euler(self):
2373
+ r"""
2374
+ Return the Euler function as an element of ``self``.
2375
+
2376
+ The *Euler function* is defined as
2377
+
2378
+ .. MATH::
2379
+
2380
+ \phi(z) = (z; z)_{\infty}
2381
+ = \sum_{n=0}^{\infty} (-1)^n q^{(3n^2-n)/2}.
2382
+
2383
+ EXAMPLES::
2384
+
2385
+ sage: L.<q> = LazyLaurentSeriesRing(ZZ)
2386
+ sage: phi = q.euler()
2387
+ sage: phi
2388
+ 1 - q - q^2 + q^5 + O(q^7)
2389
+
2390
+ We verify that `1 / phi` gives the generating function
2391
+ for all partitions::
2392
+
2393
+ sage: P = 1 / phi; P
2394
+ 1 + q + 2*q^2 + 3*q^3 + 5*q^4 + 7*q^5 + 11*q^6 + O(q^7)
2395
+ sage: P[:20] == [Partitions(n).cardinality() for n in range(20)] # needs sage.libs.flint
2396
+ True
2397
+
2398
+ TESTS::
2399
+
2400
+ sage: L.<q> = LazyLaurentSeriesRing(LazyDirichletSeriesRing(QQ, "s"))
2401
+ sage: q.euler() # needs sage.symbolic
2402
+ 1 - q - q^2 + q^5 + O(q^7)
2403
+
2404
+ REFERENCES:
2405
+
2406
+ - :wikipedia:`Euler_function`
2407
+ """
2408
+ def coeff(n):
2409
+ k = ZZ(24 * n + 1)
2410
+ m, rem = k.sqrtrem()
2411
+ if rem:
2412
+ return ZZ.zero()
2413
+ return (-1) ** ((m + 1) // 6)
2414
+ return self(coefficients=coeff, valuation=0)
2415
+
2416
+ def jacobi_theta(self, w, a=0, b=0):
2417
+ r"""
2418
+ Return the Jacobi function `\vartheta_{ab}(w; q)` as an
2419
+ element of ``self``.
2420
+
2421
+ The *Jacobi theta functions* with nome `q = \exp(\pi i \tau)`
2422
+ for `z \in \CC` and `\tau \in \RR + \RR_{>0} i`, are defined as
2423
+
2424
+ .. MATH::
2425
+
2426
+ \begin{aligned}
2427
+ \vartheta_{00}(z; \tau) & = \sum_{n=0}^{\infty}
2428
+ (w^{2n} + w^{-2n}) q^{n^2},
2429
+ \|
2430
+ \vartheta_{01}(z; \tau) & = \sum_{n=0}^{\infty}
2431
+ (-1)^n (w^{2n} + w^{-2n}) q^{n^2},
2432
+ \\
2433
+ \vartheta_{10}(z; \tau) & = \sum_{n=0}^{\infty}
2434
+ (w^{2n+1} + w^{-2n+1}) q^{n^2+n},
2435
+ \\
2436
+ \vartheta_{11}(z; \tau) & = \sum_{n=0}^{\infty}
2437
+ (-1)^n (w^{2n+1} + w^{-2n+1}) q^{n^2+n},
2438
+ \end{aligned}
2439
+
2440
+ where `w = \exp(\pi i z)`. We consider them as formal power
2441
+ series in `q` with the coefficients in the Laurent polynomial
2442
+ ring `R[w, w^{-1}]` (for a commutative ring `R`). Here, we
2443
+ deviate from the standard definition of `\theta_{10}` and
2444
+ `\theta_{11}` by removing the overall factor of `q^{1/4}`
2445
+ and `i q^{1/4}`, respectively.
2446
+
2447
+ EXAMPLES::
2448
+
2449
+ sage: R.<w> = LaurentPolynomialRing(QQ)
2450
+ sage: L.<q> = LazyPowerSeriesRing(R)
2451
+ sage: L.options.display_length = 17 # to display more coefficients
2452
+ sage: theta = q.jacobi_theta(w)
2453
+ sage: theta
2454
+ 1 + ((w^-2+w^2)*q) + ((w^-4+w^4)*q^4) + ((w^-6+w^6)*q^9)
2455
+ + ((w^-8+w^8)*q^16) + O(q^17)
2456
+
2457
+ sage: th3 = q.jacobi_theta(1, 0, 0); th3
2458
+ 1 + 2*q + 2*q^4 + 2*q^9 + 2*q^16 + O(q^17)
2459
+ sage: th2 = q.jacobi_theta(1, 1, 0); th2
2460
+ 2 + 2*q^2 + 2*q^6 + 2*q^12 + O(q^17)
2461
+ sage: th4 = q.jacobi_theta(1, 0, 1); th4
2462
+ 1 + (-2*q) + 2*q^4 + (-2*q^9) + 2*q^16 + O(q^17)
2463
+ sage: th1 = -q.jacobi_theta(1, 1, 1); th1
2464
+ -2 + 2*q^2 + (-2*q^6) + 2*q^12 + O(q^17)
2465
+
2466
+ We verify the Jacobi triple product formula::
2467
+
2468
+ sage: JTP = L.prod(lambda n: ((1 - q^(2*n)) * (1 + w^2*q^(2*n-1))
2469
+ ....: * (1 + w^-2*q^(2*n-1))), 1, oo)
2470
+ sage: JTP
2471
+ 1 + ((w^-2+w^2)*q) + ((w^-4+w^4)*q^4) + ((w^-6+w^6)*q^9)
2472
+ + ((w^-8+w^8)*q^16) + O(q^17)
2473
+ sage: JTP[:30] == theta[:30]
2474
+ True
2475
+
2476
+ We verify the Jacobi identity::
2477
+
2478
+ sage: LHS = q.jacobi_theta(1, 0, 1)^4 + q*q.jacobi_theta(1, 1, 0)^4
2479
+ sage: LHS
2480
+ 1 + 8*q + 24*q^2 + 32*q^3 + 24*q^4 + 48*q^5 + 96*q^6 + 64*q^7
2481
+ + 24*q^8 + 104*q^9 + 144*q^10 + 96*q^11 + 96*q^12 + 112*q^13
2482
+ + 192*q^14 + 192*q^15 + 24*q^16 + O(q^17)
2483
+ sage: RHS = q.jacobi_theta(1, 0, 0)^4
2484
+ sage: RHS
2485
+ 1 + 8*q + 24*q^2 + 32*q^3 + 24*q^4 + 48*q^5 + 96*q^6 + 64*q^7
2486
+ + 24*q^8 + 104*q^9 + 144*q^10 + 96*q^11 + 96*q^12 + 112*q^13
2487
+ + 192*q^14 + 192*q^15 + 24*q^16 + O(q^17)
2488
+ sage: LHS[:20] == RHS[:20]
2489
+ True
2490
+
2491
+ We verify some relationships to the (rescaled) Dedekind eta function::
2492
+
2493
+ sage: eta = q.euler()
2494
+ sage: RHS = 2 * eta(q^4)^2 / eta(q^2); RHS
2495
+ 2 + 2*q^2 + 2*q^6 + 2*q^12 + O(q^17)
2496
+ sage: th2[:30] == RHS[:30]
2497
+ True
2498
+
2499
+ sage: RHS = eta(q^2)^5 / (eta^2 * eta(q^4)^2); RHS
2500
+ 1 + 2*q + 2*q^4 + 2*q^9 + 2*q^16 + O(q^17)
2501
+ sage: th3[:30] == RHS[:30]
2502
+ True
2503
+
2504
+ sage: RHS = eta^2 / eta(q^2); RHS
2505
+ 1 + (-2*q) + 2*q^4 + (-2*q^9) + 2*q^16 + O(q^17)
2506
+ sage: th4[:30] == RHS[:30]
2507
+ True
2508
+
2509
+ sage: LHS = th2 * th3 * th4; LHS
2510
+ 2 + (-6*q^2) + 10*q^6 + (-14*q^12) + O(q^17)
2511
+ sage: RHS = 2 * eta(q^2)^3; RHS
2512
+ 2 + (-6*q^2) + 10*q^6 + (-14*q^12) + O(q^17)
2513
+ sage: LHS[:30] == RHS[:30]
2514
+ True
2515
+
2516
+ We verify some derivative formulas (recall our conventions)::
2517
+
2518
+ sage: LHS = th4 * th3.derivative() - th3 * th4.derivative(); LHS
2519
+ 4 + (-24*q^4) + 36*q^8 + 40*q^12 + (-120*q^16) + O(q^17)
2520
+ sage: RHS = th3 * th4 * (th3^4 - th4^4) / (4*q); RHS
2521
+ 4 + (-24*q^4) + 36*q^8 + 40*q^12 + O(q^16)
2522
+ sage: LHS[:30] == RHS[:30]
2523
+ True
2524
+
2525
+ sage: LHS = (th2 / th3) / (4*q) + (th2 / th3).derivative(); LHS
2526
+ 1/2/q - 5 + 45/2*q + (-65*q^2) + 153*q^3 + (-336*q^4) + 1375/2*q^5
2527
+ + (-1305*q^6) + 2376*q^7 + (-4181*q^8) + 7093*q^9 + (-11745*q^10)
2528
+ + 38073/2*q^11 + (-30157*q^12) + 46968*q^13 + (-72041*q^14)
2529
+ + 108810*q^15 + O(q^16)
2530
+ sage: RHS = th2 * th4^4 / (4 * q * th3); RHS
2531
+ 1/2/q - 5 + 45/2*q + (-65*q^2) + 153*q^3 + (-336*q^4) + 1375/2*q^5
2532
+ + (-1305*q^6) + 2376*q^7 + (-4181*q^8) + 7093*q^9 + (-11745*q^10)
2533
+ + 38073/2*q^11 + (-30157*q^12) + 46968*q^13 + (-72041*q^14)
2534
+ + 108810*q^15 + O(q^16)
2535
+ sage: LHS[:30] == RHS[:30]
2536
+ True
2537
+
2538
+ sage: LHS = (th2 / th4) / (4*q) + (th2 / th4).derivative(); LHS
2539
+ 1/2/q + 5 + 45/2*q + 65*q^2 + 153*q^3 + 336*q^4 + 1375/2*q^5
2540
+ + 1305*q^6 + 2376*q^7 + 4181*q^8 + 7093*q^9 + 11745*q^10
2541
+ + 38073/2*q^11 + 30157*q^12 + 46968*q^13 + 72041*q^14
2542
+ + 108810*q^15 + O(q^16)
2543
+ sage: RHS = th2 * th3^4 / (4 * q * th4); RHS
2544
+ 1/2/q + 5 + 45/2*q + 65*q^2 + 153*q^3 + 336*q^4 + 1375/2*q^5
2545
+ + 1305*q^6 + 2376*q^7 + 4181*q^8 + 7093*q^9 + 11745*q^10
2546
+ + 38073/2*q^11 + 30157*q^12 + 46968*q^13 + 72041*q^14
2547
+ + 108810*q^15 + O(q^16)
2548
+ sage: LHS[:30] == RHS[:30]
2549
+ True
2550
+
2551
+ sage: LHS = (th3 / th4).derivative(); LHS
2552
+ 4 + 16*q + 48*q^2 + 128*q^3 + 280*q^4 + 576*q^5 + 1120*q^6 + 2048*q^7
2553
+ + 3636*q^8 + 6240*q^9 + 10384*q^10 + 16896*q^11 + 26936*q^12
2554
+ + 42112*q^13 + 64800*q^14 + 98304*q^15 + 147016*q^16 + O(q^17)
2555
+ sage: RHS = (th3^5 - th3 * th4^4) / (4 * q * th4); RHS
2556
+ 4 + 16*q + 48*q^2 + 128*q^3 + 280*q^4 + 576*q^5 + 1120*q^6 + 2048*q^7
2557
+ + 3636*q^8 + 6240*q^9 + 10384*q^10 + 16896*q^11 + 26936*q^12
2558
+ + 42112*q^13 + 64800*q^14 + 98304*q^15 + O(q^16)
2559
+ sage: LHS[:30] == RHS[:30]
2560
+ True
2561
+
2562
+ We have the partition generating function::
2563
+
2564
+ sage: P = th3^(-1/6) * th4^(-2/3) * ((th3^4 - th4^4)/(16*q))^(-1/24); P
2565
+ 1 + q + 2*q^2 + 3*q^3 + 5*q^4 + 7*q^5 + 11*q^6 + 15*q^7 + 22*q^8
2566
+ + 30*q^9 + 42*q^10 + 56*q^11 + 77*q^12 + 101*q^13 + 135*q^14
2567
+ + 176*q^15 + 231*q^16 + O(q^17)
2568
+ sage: 1 / q.euler()
2569
+ 1 + q + 2*q^2 + 3*q^3 + 5*q^4 + 7*q^5 + 11*q^6 + 15*q^7 + 22*q^8
2570
+ + 30*q^9 + 42*q^10 + 56*q^11 + 77*q^12 + 101*q^13 + 135*q^14
2571
+ + 176*q^15 + 231*q^16 + O(q^17)
2572
+ sage: oeis(P[:30]) # optional - internet
2573
+ 0: A000041: a(n) is the number of partitions of n (the partition numbers).
2574
+ ...
2575
+
2576
+ We have the strict partition generating function::
2577
+
2578
+ sage: SP = th3^(1/6) * th4^(-1/3) * ((th3^4 - th4^4)/(16*q))^(1/24); SP
2579
+ 1 + q + q^2 + 2*q^3 + 2*q^4 + 3*q^5 + 4*q^6 + 5*q^7 + 6*q^8 + 8*q^9
2580
+ + 10*q^10 + 12*q^11 + 15*q^12 + 18*q^13 + 22*q^14 + 27*q^15
2581
+ + 32*q^16 + O(q^17)
2582
+ sage: oeis(SP[:30]) # optional - internet
2583
+ 0: A000009: Expansion of Product_{m >= 1} (1 + x^m);
2584
+ number of partitions of n into distinct parts;
2585
+ number of partitions of n into odd parts.
2586
+ 1: A081360: Expansion of q^(-1/24) (m (1-m) / 16)^(1/24) in
2587
+ powers of q, where m = k^2 is the parameter and q is the nome
2588
+ for Jacobian elliptic functions.
2589
+
2590
+ We have the overpartition generating function::
2591
+
2592
+ sage: ~th4
2593
+ 1 + 2*q + 4*q^2 + 8*q^3 + 14*q^4 + 24*q^5 + 40*q^6 + 64*q^7 + 100*q^8
2594
+ + 154*q^9 + 232*q^10 + 344*q^11 + 504*q^12 + 728*q^13 + 1040*q^14
2595
+ + 1472*q^15 + 2062*q^16 + O(q^17)
2596
+ sage: oeis((~th4)[:20]) # optional - internet
2597
+ 0: A015128: Number of overpartitions of n: ... overlined.
2598
+ 1: A004402: Expansion of 1 / Sum_{n=-oo..oo} x^(n^2).
2599
+
2600
+ We give an example over the :class:`SymbolicRing` with the input
2601
+ `w = e^{\pi i z}` and verify the periodicity::
2602
+
2603
+ sage: # needs sage.symbolic
2604
+ sage: L.<q> = LazyLaurentSeriesRing(SR)
2605
+ sage: z = SR.var('z')
2606
+ sage: theta = L.jacobi_theta(exp(pi*I*z))
2607
+ sage: theta
2608
+ 1 + (e^(2*I*pi*z) + e^(-2*I*pi*z))*q
2609
+ + (e^(4*I*pi*z) + e^(-4*I*pi*z))*q^4
2610
+ + (e^(6*I*pi*z) + e^(-6*I*pi*z))*q^9
2611
+ + (e^(8*I*pi*z) + e^(-8*I*pi*z))*q^16 + O(q^17)
2612
+ sage: theta.map_coefficients(lambda c: c(z=z+1))
2613
+ 1 + (e^(2*I*pi*z) + e^(-2*I*pi*z))*q
2614
+ + (e^(4*I*pi*z) + e^(-4*I*pi*z))*q^4
2615
+ + (e^(6*I*pi*z) + e^(-6*I*pi*z))*q^9
2616
+ + (e^(8*I*pi*z) + e^(-8*I*pi*z))*q^16 + O(q^17)
2617
+ sage: L.options._reset() # reset options
2618
+
2619
+ REFERENCES:
2620
+
2621
+ - :wikipedia:`Theta_function`
2622
+ """
2623
+ if a == 0 and b == 0:
2624
+ def coeff(n):
2625
+ if n == 0:
2626
+ return ZZ.one()
2627
+ nrt, rem = ZZ(n).sqrtrem()
2628
+ return (w**(2*nrt) + w**(-2*nrt)) if not rem else ZZ.zero()
2629
+
2630
+ if a == 0 and b == 1:
2631
+ def coeff(n):
2632
+ if n == 0:
2633
+ return ZZ.one()
2634
+ nrt, rem = ZZ(n).sqrtrem()
2635
+ return (-1)**nrt * (w**(2*nrt) + w**(-2*nrt)) if not rem else ZZ.zero()
2636
+
2637
+ if a == 1 and b == 0:
2638
+ def coeff(n):
2639
+ if n == 0:
2640
+ return w + ~w
2641
+ nrt, rem = ZZ(n).sqrtrem()
2642
+ return (w**(2*nrt+1) + w**(-2*nrt-1)) if rem == nrt else ZZ.zero()
2643
+
2644
+ if a == 1 and b == 1:
2645
+ def coeff(n):
2646
+ if n == 0:
2647
+ return w + ~w
2648
+ nrt, rem = ZZ(n).sqrtrem()
2649
+ return (-1)**nrt * (w**(2*nrt+1) + w**(-2*nrt-1)) if rem == nrt else ZZ.zero()
2650
+
2651
+ return self(coefficients=coeff, valuation=0)
2652
+
2653
+ def polylog(self, s):
2654
+ r"""
2655
+ Return the polylogarithm at ``s`` as an element in ``self``.
2656
+
2657
+ The *polylogarithm* at `s` is the power series in `z`
2658
+
2659
+ .. MATH::
2660
+
2661
+ \mathrm{Li}_s(z) = \sum_{k=1}^{\infty} \frac{z^k}{k^s}.
2662
+
2663
+ EXAMPLES::
2664
+
2665
+ sage: L.<z> = LazyLaurentSeriesRing(QQ)
2666
+ sage: L.polylog(1)
2667
+ z + 1/2*z^2 + 1/3*z^3 + 1/4*z^4 + 1/5*z^5 + 1/6*z^6 + 1/7*z^7 + O(z^8)
2668
+ sage: -log(1 - z)
2669
+ z + 1/2*z^2 + 1/3*z^3 + 1/4*z^4 + 1/5*z^5 + 1/6*z^6 + 1/7*z^7 + O(z^8)
2670
+ sage: L.polylog(2)
2671
+ z + 1/4*z^2 + 1/9*z^3 + 1/16*z^4 + 1/25*z^5 + 1/36*z^6 + 1/49*z^7 + O(z^8)
2672
+ sage: (-log(1-z) / z).integral()
2673
+ z + 1/4*z^2 + 1/9*z^3 + 1/16*z^4 + 1/25*z^5 + 1/36*z^6 + O(z^7)
2674
+ sage: L.polylog(0)
2675
+ z + z^2 + z^3 + O(z^4)
2676
+ sage: L.polylog(-1)
2677
+ z + 2*z^2 + 3*z^3 + 4*z^4 + 5*z^5 + 6*z^6 + 7*z^7 + O(z^8)
2678
+ sage: z / (1-z)^2
2679
+ z + 2*z^2 + 3*z^3 + 4*z^4 + 5*z^5 + 6*z^6 + 7*z^7 + O(z^8)
2680
+ sage: L.polylog(-2)
2681
+ z + 4*z^2 + 9*z^3 + 16*z^4 + 25*z^5 + 36*z^6 + 49*z^7 + O(z^8)
2682
+ sage: z * (1 + z) / (1 - z)^3
2683
+ z + 4*z^2 + 9*z^3 + 16*z^4 + 25*z^5 + 36*z^6 + 49*z^7 + O(z^8)
2684
+
2685
+ We can compute the Eulerian numbers::
2686
+
2687
+ sage: [L.polylog(-n) * (1-z)^(n+1) for n in range(1, 6)]
2688
+ [z + O(z^8),
2689
+ z + z^2 + O(z^8),
2690
+ z + 4*z^2 + z^3 + O(z^8),
2691
+ z + 11*z^2 + 11*z^3 + z^4 + O(z^8),
2692
+ z + 26*z^2 + 66*z^3 + 26*z^4 + z^5 + O(z^8)]
2693
+
2694
+ REFERENCES:
2695
+
2696
+ - :wikipedia:`Polylogarithm`
2697
+ """
2698
+ if not s:
2699
+ coeff_stream = Stream_exact([], constant=self.base_ring().one(), order=1)
2700
+ return self.element_class(self, coeff_stream)
2701
+ R = self.base_ring()
2702
+ return self(coefficients=lambda n: R(n) ** -s, valuation=1)
2703
+
2704
+ def dilog(self):
2705
+ r"""
2706
+ Return the dilogarithm as an element in ``self``.
2707
+
2708
+ .. SEEALSO::
2709
+
2710
+ :meth:`polylog`
2711
+
2712
+ EXAMPLES::
2713
+
2714
+ sage: L.<z> = LazyLaurentSeriesRing(QQ)
2715
+ sage: L.dilog()
2716
+ z + 1/4*z^2 + 1/9*z^3 + 1/16*z^4 + 1/25*z^5 + 1/36*z^6 + 1/49*z^7 + O(z^8)
2717
+ sage: L.polylog(2)
2718
+ z + 1/4*z^2 + 1/9*z^3 + 1/16*z^4 + 1/25*z^5 + 1/36*z^6 + 1/49*z^7 + O(z^8)
2719
+
2720
+ sage: # needs sage.symbolic
2721
+ sage: L.<x> = LazyLaurentSeriesRing(SR)
2722
+ sage: L.dilog()
2723
+ x + 1/4*x^2 + 1/9*x^3 + 1/16*x^4 + 1/25*x^5 + 1/36*x^6 + 1/49*x^7 + O(x^8)
2724
+
2725
+ REFERENCES:
2726
+
2727
+ - :wikipedia:`Dilogarithm`
2728
+ """
2729
+ return self.polylog(2)
2730
+
2731
+ ######################################################################
2732
+
2733
+
2734
+ class LazyPowerSeriesRing(LazySeriesRing):
2735
+ """
2736
+ The ring of (possibly multivariate) lazy Taylor series.
2737
+
2738
+ INPUT:
2739
+
2740
+ - ``base_ring`` -- base ring of this Taylor series ring
2741
+ - ``names`` -- name(s) of the generator of this Taylor series ring
2742
+ - ``sparse`` -- boolean (default: ``True``); whether this series is sparse or not
2743
+
2744
+ EXAMPLES::
2745
+
2746
+ sage: LazyPowerSeriesRing(ZZ, 't')
2747
+ Lazy Taylor Series Ring in t over Integer Ring
2748
+
2749
+ sage: L.<x, y> = LazyPowerSeriesRing(QQ); L
2750
+ Multivariate Lazy Taylor Series Ring in x, y over Rational Field
2751
+ """
2752
+ Element = LazyPowerSeries
2753
+
2754
+ # Follow the "generic" normalization
2755
+ __classcall_private__ = LazySeriesRing.__classcall_private__
2756
+
2757
+ def __init__(self, base_ring, names, sparse=True, category=None):
2758
+ """
2759
+ Initialize ``self``.
2760
+
2761
+ TESTS::
2762
+
2763
+ sage: LazyPowerSeriesRing.options.halting_precision(12)
2764
+
2765
+ sage: L = LazyPowerSeriesRing(ZZ, 't')
2766
+ sage: TestSuite(L).run(skip='_test_fraction_field')
2767
+ sage: L = LazyPowerSeriesRing(ZZ, 's, t')
2768
+ sage: TestSuite(L).run(skip='_test_fraction_field')
2769
+
2770
+ sage: L = LazyPowerSeriesRing(QQ, 't')
2771
+ sage: TestSuite(L).run(skip='_test_fraction_field')
2772
+ sage: L = LazyPowerSeriesRing(QQ, 's, t')
2773
+ sage: TestSuite(L).run(skip='_test_fraction_field')
2774
+
2775
+ sage: L = LazyPowerSeriesRing(GF(5), 't')
2776
+ sage: TestSuite(L).run()
2777
+
2778
+ sage: L = LazyPowerSeriesRing(GF(5), 's, t')
2779
+ sage: TestSuite(L).run(skip=['_test_fraction_field'])
2780
+
2781
+ sage: L = LazyPowerSeriesRing(Zmod(6), 't')
2782
+ sage: TestSuite(L).run(skip=['_test_revert'])
2783
+ sage: L = LazyPowerSeriesRing(Zmod(6), 's, t')
2784
+ sage: TestSuite(L).run(skip=['_test_revert'])
2785
+
2786
+ sage: L = LazyPowerSeriesRing(QQ['q'], 't')
2787
+ sage: TestSuite(L).run(skip='_test_fraction_field')
2788
+ sage: L = LazyPowerSeriesRing(QQ['q'], 's, t')
2789
+ sage: TestSuite(L).run(skip='_test_fraction_field') # long time
2790
+
2791
+ sage: L = LazyPowerSeriesRing(ZZ['q'], 't')
2792
+ sage: TestSuite(L).run(skip='_test_fraction_field')
2793
+ sage: L = LazyPowerSeriesRing(ZZ['q'], 's, t')
2794
+ sage: TestSuite(L).run(skip='_test_fraction_field') # long time
2795
+
2796
+ sage: LazyPowerSeriesRing.options._reset() # reset the options
2797
+
2798
+ Check that :issue:`34470` is fixed::
2799
+
2800
+ sage: L.<t> = LazyPowerSeriesRing(QQ)
2801
+ sage: L in CompleteDiscreteValuationRings
2802
+ True
2803
+ sage: L.uniformizer()
2804
+ t
2805
+ sage: lcm(1/(1 - t^2) - 1, t)
2806
+ t^2
2807
+
2808
+ sage: L.<t> = LazyPowerSeriesRing(ZZ)
2809
+ sage: L in PrincipalIdealDomains
2810
+ False
2811
+
2812
+ The ideal generated by `s` and `t` is not principal::
2813
+
2814
+ sage: L = LazyPowerSeriesRing(QQ, 's, t')
2815
+ sage: L in PrincipalIdealDomains
2816
+ False
2817
+ """
2818
+ self._sparse = sparse
2819
+ self._minimal_valuation = 0
2820
+ self._arity = len(names)
2821
+ if self._arity == 1:
2822
+ self._laurent_poly_ring = PolynomialRing(base_ring, names, sparse=sparse)
2823
+ self._internal_poly_ring = self._laurent_poly_ring
2824
+ else:
2825
+ self._laurent_poly_ring = PolynomialRing(base_ring, names)
2826
+ self._internal_poly_ring = PolynomialRing(self._laurent_poly_ring, "DUMMY_VARIABLE", sparse=sparse)
2827
+ category = Algebras(base_ring.category())
2828
+ mixin_gcd = False
2829
+ if self._arity == 1:
2830
+ if base_ring in Fields():
2831
+ category &= CompleteDiscreteValuationRings()
2832
+ mixin_gcd = True
2833
+ elif base_ring in Fields():
2834
+ category &= UniqueFactorizationDomains()
2835
+ mixin_gcd = True
2836
+ if base_ring in IntegralDomains():
2837
+ category &= IntegralDomains()
2838
+ elif base_ring in Rings().Commutative():
2839
+ category = category.Commutative()
2840
+
2841
+ if mixin_gcd:
2842
+ from sage.structure.dynamic_class import dynamic_class
2843
+ self.Element = dynamic_class(
2844
+ f"{self.Element.__name__}_gcd",
2845
+ (self.Element, LazyPowerSeries_gcd_mixin),
2846
+ doccls=self.Element)
2847
+
2848
+ if base_ring.is_zero():
2849
+ category = category.Finite()
2850
+ else:
2851
+ category = category.Infinite()
2852
+ Parent.__init__(self, base=base_ring, names=names,
2853
+ category=category)
2854
+
2855
+ def construction(self):
2856
+ """
2857
+ Return a pair ``(F, R)``, where ``F`` is a
2858
+ :class:`CompletionFunctor` and `R` is a ring, such that
2859
+ ``F(R)`` returns ``self``.
2860
+
2861
+ EXAMPLES::
2862
+
2863
+ sage: L = LazyPowerSeriesRing(ZZ, 't')
2864
+ sage: L.construction()
2865
+ (Completion[t, prec=+Infinity],
2866
+ Sparse Univariate Polynomial Ring in t over Integer Ring)
2867
+ """
2868
+ from sage.categories.pushout import CompletionFunctor
2869
+ if self._arity == 1:
2870
+ return (CompletionFunctor(self._names[0], infinity),
2871
+ self._laurent_poly_ring)
2872
+ return (CompletionFunctor(self._names, infinity),
2873
+ self._laurent_poly_ring)
2874
+
2875
+ def _repr_(self):
2876
+ """
2877
+ String representation of this Taylor series ring.
2878
+
2879
+ EXAMPLES::
2880
+
2881
+ sage: LazyPowerSeriesRing(GF(2), 'z')
2882
+ Lazy Taylor Series Ring in z over Finite Field of size 2
2883
+ """
2884
+ BR = self.base_ring()
2885
+ if len(self.variable_names()) == 1:
2886
+ return "Lazy Taylor Series Ring in {} over {}".format(self.variable_name(), BR)
2887
+ generators_rep = ", ".join(self.variable_names())
2888
+ return "Multivariate Lazy Taylor Series Ring in {} over {}".format(generators_rep, BR)
2889
+
2890
+ def _latex_(self):
2891
+ r"""
2892
+ Return a latex representation of ``self``.
2893
+
2894
+ EXAMPLES::
2895
+
2896
+ sage: L = LazyPowerSeriesRing(GF(2), 'z')
2897
+ sage: latex(L)
2898
+ \Bold{F}_{2} [\![z]\!]
2899
+ """
2900
+ from sage.misc.latex import latex
2901
+ generators_rep = ", ".join(self.variable_names())
2902
+ return latex(self.base_ring()) + r"[\![{}]\!]".format(generators_rep)
2903
+
2904
+ def _monomial(self, c, n):
2905
+ r"""
2906
+ Return the interpretation of the coefficient ``c`` at index ``n``.
2907
+
2908
+ EXAMPLES::
2909
+
2910
+ sage: L = LazyPowerSeriesRing(ZZ, 'z')
2911
+ sage: L._monomial(2, 3)
2912
+ 2*z^3
2913
+ """
2914
+ m = len(self.variable_names())
2915
+ L = self._laurent_poly_ring
2916
+ if m == 1:
2917
+ return L(c) * L.gen() ** n
2918
+ return L(c)
2919
+
2920
+ @cached_method
2921
+ def _terms_of_degree(self, n, R):
2922
+ r"""
2923
+ Return the list of monomials of degree ``n`` in the polynomial
2924
+ ring with base ring ``R``.
2925
+
2926
+ EXAMPLES::
2927
+
2928
+ sage: L.<x> = LazyPowerSeriesRing(ZZ)
2929
+ sage: m = L._terms_of_degree(3, QQ["z"]); m
2930
+ [1]
2931
+ sage: m[0].parent()
2932
+ Univariate Polynomial Ring in z over Rational Field
2933
+ sage: L.<x, y> = LazyPowerSeriesRing(ZZ)
2934
+ sage: m = L._terms_of_degree(3, QQ["z"]); m # needs sage.combinat
2935
+ [y^3, x*y^2, x^2*y, x^3]
2936
+ sage: m[0].parent() # needs sage.combinat
2937
+ Multivariate Polynomial Ring in x, y over Univariate Polynomial Ring in z over Rational Field
2938
+ """
2939
+ if self._arity == 1:
2940
+ return [R.one()]
2941
+ return [m.change_ring(R)
2942
+ for m in self._internal_poly_ring.base_ring().monomials_of_degree(n)]
2943
+
2944
+ @cached_method
2945
+ def gen(self, n=0):
2946
+ """
2947
+ Return the ``n``-th generator of ``self``.
2948
+
2949
+ EXAMPLES::
2950
+
2951
+ sage: L = LazyPowerSeriesRing(ZZ, 'z')
2952
+ sage: L.gen()
2953
+ z
2954
+ sage: L.gen(3)
2955
+ Traceback (most recent call last):
2956
+ ...
2957
+ IndexError: there is only one generator
2958
+ """
2959
+ m = len(self.variable_names())
2960
+ if n > m:
2961
+ if m == 1:
2962
+ raise IndexError("there is only one generator")
2963
+ raise IndexError("there are only %s generators" % m)
2964
+
2965
+ R = self._laurent_poly_ring
2966
+ BR = self.base_ring()
2967
+ if len(self.variable_names()) == 1:
2968
+ coeff_stream = Stream_exact([BR.one()], constant=BR.zero(), order=1)
2969
+ else:
2970
+ coeff_stream = Stream_exact([R.gen(n)], constant=R.zero(), order=1)
2971
+ return self.element_class(self, coeff_stream)
2972
+
2973
+ def ngens(self):
2974
+ r"""
2975
+ Return the number of generators of ``self``.
2976
+
2977
+ EXAMPLES::
2978
+
2979
+ sage: L.<z> = LazyPowerSeriesRing(ZZ)
2980
+ sage: L.ngens()
2981
+ 1
2982
+ """
2983
+ return len(self.variable_names())
2984
+
2985
+ @cached_method
2986
+ def gens(self) -> tuple:
2987
+ """
2988
+ Return the generators of ``self``.
2989
+
2990
+ EXAMPLES::
2991
+
2992
+ sage: L = LazyPowerSeriesRing(ZZ, 'x,y')
2993
+ sage: L.gens()
2994
+ (x, y)
2995
+ """
2996
+ return tuple([self.gen(n) for n in range(self.ngens())])
2997
+
2998
+ def _element_constructor_(self, x=None, valuation=None, constant=None, degree=None, coefficients=None, check=True):
2999
+ """
3000
+ Construct a Taylor series from ``x``.
3001
+
3002
+ INPUT:
3003
+
3004
+ - ``x`` -- data used to the define a Taylor series
3005
+ - ``valuation`` -- integer (optional); a lower bound for the valuation
3006
+ of the series
3007
+ - ``constant`` -- (optional) the eventual constant of the series
3008
+ - ``degree`` -- (optional) the degree when the series is ``constant``
3009
+ - ``check`` -- (optional) check that coefficients are homogeneous of
3010
+ the correct degree when they are retrieved
3011
+
3012
+ .. WARNING::
3013
+
3014
+ The behaviour of ``LazyPowerSeries(c)`` for a list ``c``
3015
+ with nonzero last element `e` changed with
3016
+ :issue:`32367`. To obtain the old behaviour, use
3017
+ ``LazyPowerSeries(c, constant=e)``.
3018
+
3019
+ EXAMPLES::
3020
+
3021
+ sage: L = LazyPowerSeriesRing(GF(2), 'z')
3022
+ sage: L(2)
3023
+ 0
3024
+ sage: L(3)
3025
+ 1
3026
+
3027
+ sage: L = LazyPowerSeriesRing(ZZ, 'z')
3028
+ sage: L(lambda i: i, 5, 1, 10)
3029
+ 5*z^5 + 6*z^6 + 7*z^7 + 8*z^8 + 9*z^9 + z^10 + z^11 + z^12 + O(z^13)
3030
+ sage: L(lambda i: i, 5, (1, 10))
3031
+ 5*z^5 + 6*z^6 + 7*z^7 + 8*z^8 + 9*z^9 + z^10 + z^11 + z^12 + O(z^13)
3032
+
3033
+ sage: X = L(constant=5, degree=2); X
3034
+ 5*z^2 + 5*z^3 + 5*z^4 + O(z^5)
3035
+ sage: X.valuation()
3036
+ 2
3037
+
3038
+ sage: e = L(lambda n: n + 1); e
3039
+ 1 + 2*z + 3*z^2 + 4*z^3 + 5*z^4 + 6*z^5 + 7*z^6 + O(z^7)
3040
+ sage: f = e^-1; f
3041
+ 1 - 2*z + z^2 + O(z^7)
3042
+ sage: f.coefficient(10)
3043
+ 0
3044
+ sage: f[20]
3045
+ 0
3046
+
3047
+ sage: L(valuation=2, constant=1)
3048
+ z^2 + z^3 + z^4 + O(z^5)
3049
+ sage: L(constant=1)
3050
+ 1 + z + z^2 + O(z^3)
3051
+
3052
+ Alternatively, ``x`` can be a list of elements of the base ring.
3053
+ Then these elements are read as coefficients of the terms of
3054
+ degrees starting from the ``valuation``. In this case, ``constant``
3055
+ may be just an element of the base ring instead of a tuple or can be
3056
+ simply omitted if it is zero::
3057
+
3058
+ sage: f = L([1,2,3,4], 1); f
3059
+ z + 2*z^2 + 3*z^3 + 4*z^4
3060
+
3061
+ sage: g = L([1,3,5,7,9], 5, -1); g
3062
+ z^5 + 3*z^6 + 5*z^7 + 7*z^8 + 9*z^9 - z^10 - z^11 - z^12 + O(z^13)
3063
+
3064
+ Additionally, ``x`` can be a polynomial::
3065
+
3066
+ sage: P.<x> = QQ[]
3067
+ sage: p = x + 3*x^2 + x^5
3068
+ sage: L.<x> = LazyPowerSeriesRing(ZZ)
3069
+ sage: L(p)
3070
+ x + 3*x^2 + x^5
3071
+
3072
+ sage: L(p, valuation=0)
3073
+ 1 + 3*x + x^4
3074
+
3075
+ sage: P.<x, y> = QQ[]
3076
+ sage: p = x + y^2 + x*y
3077
+ sage: L.<x,y> = LazyPowerSeriesRing(ZZ)
3078
+ sage: L(p)
3079
+ x + (x*y+y^2)
3080
+
3081
+ Finally ``x`` can be in the corresponding fraction field::
3082
+
3083
+ sage: R.<a,b,c> = PolynomialRing(ZZ)
3084
+ sage: L = LazyPowerSeriesRing(ZZ, 'a,b,c')
3085
+ sage: aa, bb, cc = L.gens()
3086
+ sage: f = (1 + a + b) / (1 + a*b + c^3); f
3087
+ (a + b + 1)/(c^3 + a*b + 1)
3088
+ sage: f.parent()
3089
+ Fraction Field of Multivariate Polynomial Ring in a, b, c over Integer Ring
3090
+ sage: L(f) # needs sage.libs.singular
3091
+ 1 + (a+b) - a*b - (a^2*b+a*b^2+c^3) + (a^2*b^2-a*c^3-b*c^3)
3092
+ + (a^3*b^2+a^2*b^3+2*a*b*c^3) - (a^3*b^3-2*a^2*b*c^3-2*a*b^2*c^3-c^6)
3093
+ + O(a,b,c)^7
3094
+ sage: L(f) == (1 + aa + bb) / (1 + aa*bb + cc^3) # needs sage.libs.singular
3095
+ True
3096
+
3097
+ TESTS::
3098
+
3099
+ sage: L.<x,y> = LazyPowerSeriesRing(ZZ)
3100
+ sage: L(constant=1)
3101
+ Traceback (most recent call last):
3102
+ ...
3103
+ ValueError: constant must be zero for multivariate Taylor series
3104
+
3105
+ sage: L(lambda n: 0)
3106
+ O(x,y)^7
3107
+
3108
+ sage: L(lambda n: n)[3];
3109
+ Traceback (most recent call last):
3110
+ ...
3111
+ ValueError: coefficient 3 at degree 3 is not a homogeneous polynomial
3112
+
3113
+ sage: L([1, 2, 3]);
3114
+ Traceback (most recent call last):
3115
+ ...
3116
+ ValueError: unable to convert [1, 2, 3] into a lazy Taylor series
3117
+
3118
+ sage: L(lambda n: n, degree=3);
3119
+ Traceback (most recent call last):
3120
+ ...
3121
+ ValueError: coefficients must be homogeneous polynomials of the correct degree
3122
+ """
3123
+ if valuation is not None:
3124
+ if valuation < 0:
3125
+ raise ValueError("the valuation of a Taylor series must be nonnegative")
3126
+ # TODO: the following is nonsense, think of an iterator
3127
+ # if self._arity > 1 and valuation != 0:
3128
+ # raise ValueError(f"valuation must not be specified for multivariate Taylor series (for {x}), but was set to {valuation}")
3129
+ if self._arity > 1:
3130
+ valuation = 0
3131
+
3132
+ R = self._laurent_poly_ring
3133
+ BR = self._internal_poly_ring.base_ring() # this is the ring containing the elements of the stream
3134
+ if x is None:
3135
+ assert degree is None
3136
+ coeff_stream = Stream_uninitialized(valuation)
3137
+ return self.element_class(self, coeff_stream)
3138
+
3139
+ try:
3140
+ # Try to build stuff using the polynomial ring constructor
3141
+ x = R(x)
3142
+ except (TypeError, ValueError, AttributeError):
3143
+ pass
3144
+ if isinstance(constant, (tuple, list)):
3145
+ constant, degree = constant
3146
+ if constant is not None:
3147
+ if self._arity > 1 and constant:
3148
+ raise ValueError("constant must be zero for multivariate Taylor series")
3149
+ constant = BR(constant)
3150
+
3151
+ if parent(x) == R:
3152
+ if not x and not constant:
3153
+ coeff_stream = Stream_zero()
3154
+ else:
3155
+ if not x:
3156
+ coeff_stream = Stream_exact([],
3157
+ order=valuation,
3158
+ degree=degree,
3159
+ constant=constant)
3160
+ return self.element_class(self, coeff_stream)
3161
+
3162
+ if self._arity == 1:
3163
+ v = x.valuation()
3164
+ d = x.degree()
3165
+ p_list = [x[i] for i in range(v, d + 1)]
3166
+ if valuation is not None:
3167
+ v = valuation
3168
+ else:
3169
+ p_dict = x.homogeneous_components()
3170
+ v = min(p_dict.keys())
3171
+ d = max(p_dict.keys())
3172
+ p_list = [p_dict.get(i, 0) for i in range(v, d + 1)]
3173
+
3174
+ coeff_stream = Stream_exact(p_list,
3175
+ order=v,
3176
+ constant=constant,
3177
+ degree=degree)
3178
+ return self.element_class(self, coeff_stream)
3179
+
3180
+ if isinstance(x, LazyPowerSeries):
3181
+ stream = x._coeff_stream
3182
+ if isinstance(stream, Stream_exact):
3183
+ coeffs = [BR(val) for val in stream._initial_coefficients]
3184
+ constant = BR(stream._constant)
3185
+ valuation = stream._approximate_order
3186
+ for i, c in enumerate(coeffs):
3187
+ if c:
3188
+ valuation += i
3189
+ coeffs = coeffs[i:]
3190
+ break
3191
+ else:
3192
+ valuation += len(coeffs)
3193
+ coeffs = []
3194
+ return self(coeffs,
3195
+ degree=stream._degree,
3196
+ constant=constant,
3197
+ valuation=valuation)
3198
+ return self.element_class(self, stream)
3199
+
3200
+ # Check if we can realize the input as a rational function
3201
+ try:
3202
+ FF = self._laurent_poly_ring.fraction_field()
3203
+ x = FF(x)
3204
+ except (TypeError, ValueError, AttributeError):
3205
+ pass
3206
+ else:
3207
+ return self(x.numerator()) / self(x.denominator())
3208
+
3209
+ if callable(x) or isinstance(x, (GeneratorType, map, filter)):
3210
+ if valuation is None:
3211
+ valuation = 0
3212
+ if degree is not None:
3213
+ if constant is None:
3214
+ constant = ZZ.zero()
3215
+ if callable(x):
3216
+ p = [x(i) for i in range(valuation, degree)]
3217
+ else:
3218
+ p = [c for c, _ in zip(_skip_leading_zeros(x), range(valuation, degree))]
3219
+ if self._arity == 1:
3220
+ p = [BR(c) for c in p]
3221
+ else:
3222
+ p = [R(c) for c in p]
3223
+ if not all(e.is_homogeneous() and e.degree() == i
3224
+ for i, e in enumerate(p, valuation)):
3225
+ raise ValueError("coefficients must be homogeneous polynomials of the correct degree")
3226
+ coeff_stream = Stream_exact(p,
3227
+ order=valuation,
3228
+ constant=constant,
3229
+ degree=degree)
3230
+ return self.element_class(self, coeff_stream)
3231
+ if check and self._arity > 1:
3232
+ if callable(x):
3233
+ def y(n):
3234
+ e = R(x(n))
3235
+ if not e or e.is_homogeneous() and e.degree() == n:
3236
+ return e
3237
+ raise ValueError("coefficient %s at degree %s is not a homogeneous polynomial" % (e, n))
3238
+ coeff_stream = Stream_function(y, self._sparse, valuation)
3239
+ else:
3240
+ coeff_stream = Stream_iterator(map(R, _skip_leading_zeros(x)), valuation)
3241
+ elif callable(x):
3242
+ coeff_stream = Stream_function(lambda i: BR(x(i)), self._sparse, valuation)
3243
+ else:
3244
+ coeff_stream = Stream_iterator(map(BR, _skip_leading_zeros(x)), valuation)
3245
+ return self.element_class(self, coeff_stream)
3246
+ raise ValueError(f"unable to convert {x} into a lazy Taylor series")
3247
+
3248
+ def _an_element_(self):
3249
+ """
3250
+ Return a Taylor series in ``self``.
3251
+
3252
+ EXAMPLES::
3253
+
3254
+ sage: L = LazyPowerSeriesRing(ZZ, 'z')
3255
+ sage: L.an_element()
3256
+ z + z^2 + z^3 + O(z^4)
3257
+
3258
+ sage: L = LazyPowerSeriesRing(ZZ, 'x, y')
3259
+ sage: L.an_element()
3260
+ x
3261
+ """
3262
+ if self._arity == 1:
3263
+ return self(self._laurent_poly_ring.an_element(),
3264
+ constant=self.base_ring().an_element())
3265
+ return self(self._laurent_poly_ring.an_element())
3266
+
3267
+ def uniformizer(self):
3268
+ """
3269
+ Return a uniformizer of ``self``.
3270
+
3271
+ EXAMPLES::
3272
+
3273
+ sage: L = LazyPowerSeriesRing(QQ, 'x')
3274
+ sage: L.uniformizer()
3275
+ x
3276
+ """
3277
+ R = self.base_ring()
3278
+ if R not in Fields():
3279
+ raise TypeError("the base ring is not a field")
3280
+ if self._arity != 1:
3281
+ raise TypeError("the arity must be one")
3282
+ return self.gen()
3283
+
3284
+ def residue_field(self):
3285
+ """
3286
+ Return the residue field of the ring of integers of ``self``.
3287
+
3288
+ EXAMPLES::
3289
+
3290
+ sage: L = LazyPowerSeriesRing(QQ, 'x')
3291
+ sage: L.residue_field()
3292
+ Rational Field
3293
+ """
3294
+ R = self.base_ring()
3295
+ if R not in Fields():
3296
+ raise TypeError("the base ring is not a field")
3297
+ if self._arity != 1:
3298
+ raise TypeError("the arity must be one")
3299
+ return R
3300
+
3301
+ def fraction_field(self):
3302
+ """
3303
+ Return the fraction field of ``self``.
3304
+
3305
+ If this is with a single variable over a field, then the fraction
3306
+ field is the field of (lazy) formal Laurent series.
3307
+
3308
+ .. TODO::
3309
+
3310
+ Implement other fraction fields.
3311
+
3312
+ EXAMPLES::
3313
+
3314
+ sage: L.<x> = LazyPowerSeriesRing(QQ)
3315
+ sage: L.fraction_field()
3316
+ Lazy Laurent Series Ring in x over Rational Field
3317
+ """
3318
+ if self not in IntegralDomains():
3319
+ raise TypeError("must be an integral domain")
3320
+ R = self.base_ring()
3321
+ if self._arity == 1 and R in Fields():
3322
+ return LazyLaurentSeriesRing(R, names=self.variable_names())
3323
+ raise NotImplementedError("the fraction field is not yet implemented")
3324
+
3325
+ def some_elements(self):
3326
+ """
3327
+ Return a list of elements of ``self``.
3328
+
3329
+ EXAMPLES::
3330
+
3331
+ sage: L = LazyPowerSeriesRing(ZZ, 'z')
3332
+ sage: L.some_elements()[:6]
3333
+ [0, 1, z + z^2 + z^3 + O(z^4),
3334
+ -12 - 8*z + z^2 + z^3,
3335
+ 1 + z - 2*z^2 - 7*z^3 - z^4 + 20*z^5 + 23*z^6 + O(z^7),
3336
+ z + 4*z^2 + 9*z^3 + 16*z^4 + 25*z^5 + 36*z^6 + O(z^7)]
3337
+
3338
+ sage: L = LazyPowerSeriesRing(GF(3)["q"], 'z')
3339
+ sage: L.some_elements()[:6]
3340
+ [0, 1, z + q*z^2 + q*z^3 + q*z^4 + O(z^5),
3341
+ z + z^2 + z^3,
3342
+ 1 + z + z^2 + 2*z^3 + 2*z^4 + 2*z^5 + O(z^6),
3343
+ z + z^2 + z^4 + z^5 + O(z^7)]
3344
+
3345
+ sage: L = LazyPowerSeriesRing(GF(3), 'q, t')
3346
+ sage: L.some_elements()[:6]
3347
+ [0, 1, q,
3348
+ q + q^2 + q^3,
3349
+ 1 + q + q^2 - q^3 - q^4 - q^5 - q^6 + O(q,t)^7,
3350
+ 1 + (q+t) + (q^2-q*t+t^2) + (q^3+t^3) + (q^4+q^3*t+q*t^3+t^4)
3351
+ + (q^5-q^4*t+q^3*t^2+q^2*t^3-q*t^4+t^5) + (q^6-q^3*t^3+t^6) + O(q,t)^7]
3352
+ """
3353
+ z = self.gen(0)
3354
+ elts = [self.zero(), self.one(), self.an_element()]
3355
+ if self._arity == 1:
3356
+ elts.extend([(z-3)*(2+z)**2, (1 - 2*z**3)/(1 - z + 3*z**2), self(lambda n: n**2)])
3357
+ else:
3358
+ PR = self._laurent_poly_ring
3359
+ sum_gens = PR.sum(PR.gens())
3360
+ elts.extend([(z-3)*(2+z)**2, (1 - 2*z**3)/(1 - z + 3*z**2), self(lambda n: sum_gens**n)])
3361
+ return elts
3362
+
3363
+ def taylor(self, f):
3364
+ r"""
3365
+ Return the Taylor expansion around `0` of the function ``f``.
3366
+
3367
+ INPUT:
3368
+
3369
+ - ``f`` -- a function such that one of the following works:
3370
+
3371
+ * the substitution `f(z_1, \ldots, z_n)`, where `(z_1, \ldots, z_n)`
3372
+ are the generators of ``self``
3373
+ * `f` is a function with no poles at `0` and has a ``derivative``
3374
+ method
3375
+
3376
+ .. WARNING::
3377
+
3378
+ For inputs as symbolic functions/expressions, this does not check
3379
+ that the function does not have poles at `0`.
3380
+
3381
+ EXAMPLES::
3382
+
3383
+ sage: # needs sage.symbolic
3384
+ sage: L.<z> = LazyPowerSeriesRing(QQ)
3385
+ sage: x = SR.var('x')
3386
+ sage: f(x) = (1 + x) / (1 - x^3)
3387
+ sage: L.taylor(f)
3388
+ 1 + z + z^3 + z^4 + z^6 + O(z^7)
3389
+ sage: (1 + z) / (1 - z^3)
3390
+ 1 + z + z^3 + z^4 + z^6 + O(z^7)
3391
+ sage: f(x) = cos(x + pi/2)
3392
+ sage: L.taylor(f)
3393
+ -z + 1/6*z^3 - 1/120*z^5 + O(z^7)
3394
+
3395
+ For inputs as symbolic functions/expressions, the function must
3396
+ not have any poles at `0`::
3397
+
3398
+ sage: # needs sage.symbolic
3399
+ sage: L.<z> = LazyPowerSeriesRing(QQ, sparse=True)
3400
+ sage: f = 1 / sin(x)
3401
+ sage: L.taylor(f)
3402
+ <repr(...) failed: ValueError: power::eval(): division by zero>
3403
+
3404
+ Different multivariate inputs::
3405
+
3406
+ sage: # needs sage.symbolic
3407
+ sage: L.<a,b> = LazyPowerSeriesRing(QQ)
3408
+ sage: def f(x, y): return (1 + x) / (1 + y)
3409
+ sage: L.taylor(f)
3410
+ 1 + (a-b) - (a*b-b^2) + (a*b^2-b^3) - (a*b^3-b^4) + (a*b^4-b^5) - (a*b^5-b^6) + O(a,b)^7
3411
+ sage: g(w, z) = (1 + w) / (1 + z)
3412
+ sage: L.taylor(g)
3413
+ 1 + (a-b) - (a*b-b^2) + (a*b^2-b^3) - (a*b^3-b^4) + (a*b^4-b^5) - (a*b^5-b^6) + O(a,b)^7
3414
+ sage: y = SR.var('y')
3415
+ sage: h = (1 + x) / (1 + y)
3416
+ sage: L.taylor(h)
3417
+ 1 + (a-b) - (a*b-b^2) + (a*b^2-b^3) - (a*b^3-b^4) + (a*b^4-b^5) - (a*b^5-b^6) + O(a,b)^7
3418
+ """
3419
+ try:
3420
+ return f(*self.gens())
3421
+ except (ValueError, TypeError):
3422
+ pass
3423
+
3424
+ if self._arity != 1:
3425
+ R = self._laurent_poly_ring
3426
+ BR = R.base_ring()
3427
+ args = f.arguments()
3428
+ subs = {str(va): ZZ.zero() for va in args}
3429
+ ell = len(subs)
3430
+ from sage.combinat.integer_vector import integer_vectors_nk_fast_iter
3431
+ from sage.arith.misc import factorial
3432
+
3433
+ def taylor_expand(deg):
3434
+ if deg == 0:
3435
+ return BR(f(**subs))
3436
+ return R.sum(BR(f.diff(*sum(([g] * e for g, e in zip(args, al)), []))(**subs)
3437
+ / ZZ.prod(factorial(a) for a in al))
3438
+ * R.monomial(*al) for al in integer_vectors_nk_fast_iter(deg, ell))
3439
+
3440
+ coeff_stream = Stream_function(taylor_expand, self._sparse, self._minimal_valuation)
3441
+ else:
3442
+ coeff_stream = Stream_taylor(f, self._sparse)
3443
+ return self.element_class(self, coeff_stream)
3444
+
3445
+
3446
+ ######################################################################
3447
+
3448
+
3449
+ class LazyCompletionGradedAlgebra(LazySeriesRing):
3450
+ r"""
3451
+ The completion of a graded algebra consisting of formal series.
3452
+
3453
+ For a graded algebra `A`, we can form a completion of `A` consisting of
3454
+ all formal series of `A` such that each homogeneous component is
3455
+ a finite linear combination of basis elements of `A`.
3456
+
3457
+ INPUT:
3458
+
3459
+ - ``basis`` -- a graded algebra
3460
+ - ``names`` -- name(s) of the alphabets
3461
+ - ``sparse`` -- boolean (default: ``True``); whether we use a sparse or
3462
+ a dense representation
3463
+
3464
+ EXAMPLES::
3465
+
3466
+ sage: # needs sage.combinat sage.modules
3467
+ sage: NCSF = NonCommutativeSymmetricFunctions(QQ)
3468
+ sage: S = NCSF.Complete()
3469
+ sage: L = S.formal_series_ring(); L
3470
+ Lazy completion of Non-Commutative Symmetric Functions
3471
+ over the Rational Field in the Complete basis
3472
+ sage: f = 1 / (1 - L(S[1])); f
3473
+ S[] + S[1] + (S[1,1]) + (S[1,1,1]) + (S[1,1,1,1]) + (S[1,1,1,1,1])
3474
+ + (S[1,1,1,1,1,1]) + O^7
3475
+ sage: g = 1 / (1 - L(S[2])); g
3476
+ S[] + S[2] + (S[2,2]) + (S[2,2,2]) + O^7
3477
+ sage: f * g
3478
+ S[] + S[1] + (S[1,1]+S[2]) + (S[1,1,1]+S[1,2])
3479
+ + (S[1,1,1,1]+S[1,1,2]+S[2,2]) + (S[1,1,1,1,1]+S[1,1,1,2]+S[1,2,2])
3480
+ + (S[1,1,1,1,1,1]+S[1,1,1,1,2]+S[1,1,2,2]+S[2,2,2]) + O^7
3481
+ sage: g * f
3482
+ S[] + S[1] + (S[1,1]+S[2]) + (S[1,1,1]+S[2,1])
3483
+ + (S[1,1,1,1]+S[2,1,1]+S[2,2]) + (S[1,1,1,1,1]+S[2,1,1,1]+S[2,2,1])
3484
+ + (S[1,1,1,1,1,1]+S[2,1,1,1,1]+S[2,2,1,1]+S[2,2,2]) + O^7
3485
+ sage: f * g - g * f
3486
+ (S[1,2]-S[2,1]) + (S[1,1,2]-S[2,1,1])
3487
+ + (S[1,1,1,2]+S[1,2,2]-S[2,1,1,1]-S[2,2,1])
3488
+ + (S[1,1,1,1,2]+S[1,1,2,2]-S[2,1,1,1,1]-S[2,2,1,1]) + O^7
3489
+ """
3490
+ Element = LazyCompletionGradedAlgebraElement
3491
+
3492
+ def __init__(self, basis, sparse=True, category=None):
3493
+ """
3494
+ Initialize ``self``.
3495
+
3496
+ TESTS::
3497
+
3498
+ sage: LazySymmetricFunctions.options.halting_precision(6) # needs sage.combinat sage.modules
3499
+
3500
+ sage: # needs sage.combinat sage.modules
3501
+ sage: s = SymmetricFunctions(QQ).s()
3502
+ sage: L = LazySymmetricFunctions(s)
3503
+ sage: TestSuite(L).run() # needs lrcalc_python
3504
+ sage: p = SymmetricFunctions(GF(5)).p()
3505
+ sage: L = LazySymmetricFunctions(p)
3506
+ sage: TestSuite(L).run()
3507
+
3508
+ Reversion will only work when the base ring is a field::
3509
+
3510
+ sage: # needs sage.combinat sage.modules
3511
+ sage: s = SymmetricFunctions(ZZ).s()
3512
+ sage: L = LazySymmetricFunctions(s)
3513
+ sage: TestSuite(L).run(skip=['_test_revert']) # needs lrcalc_python
3514
+ sage: s = SymmetricFunctions(QQ["q"]).s()
3515
+ sage: L = LazySymmetricFunctions(s)
3516
+ sage: TestSuite(L).run(skip=['_test_revert']) # needs lrcalc_python
3517
+
3518
+ Options are remembered across doctests::
3519
+
3520
+ sage: LazySymmetricFunctions.options._reset() # needs sage.combinat sage.modules
3521
+
3522
+ Check that :issue:`34470` is fixed. The ideal generated by
3523
+ `p[1]` and `p[2]` is not principal::
3524
+
3525
+ sage: p = SymmetricFunctions(QQ).p() # needs sage.combinat sage.modules
3526
+ sage: L = LazySymmetricFunctions(s) # needs sage.combinat sage.modules
3527
+ sage: L in PrincipalIdealDomains # needs sage.combinat sage.modules
3528
+ False
3529
+
3530
+ Check that a basis which is not graded is not enough::
3531
+
3532
+ sage: ht = SymmetricFunctions(ZZ).ht() # needs sage.combinat sage.modules
3533
+ sage: L = LazySymmetricFunctions(ht) # needs sage.combinat sage.modules
3534
+ Traceback (most recent call last):
3535
+ ...
3536
+ ValueError: basis should be in GradedAlgebrasWithBasis
3537
+
3538
+ Check that :issue:`37625` is fixed::
3539
+
3540
+ sage: # needs sage.combinat sage.modules
3541
+ sage: R = algebras.Free(QQ, ('a', 'b'), degrees=(1, 2))
3542
+ sage: L = R.completion()
3543
+ sage: a, b = R.gens()
3544
+ sage: (L(a) + L(b))^2
3545
+ a^2 + (a*b+b*a) + b^2
3546
+ """
3547
+ base_ring = basis.base_ring()
3548
+ self._minimal_valuation = 0
3549
+ if basis in Algebras.TensorProducts:
3550
+ self._arity = len(basis._sets)
3551
+ else:
3552
+ if basis not in GradedAlgebrasWithBasis:
3553
+ raise ValueError("basis should be in GradedAlgebrasWithBasis")
3554
+ self._arity = 1
3555
+ category = Algebras(basis.category())
3556
+ if basis in IntegralDomains():
3557
+ category &= IntegralDomains()
3558
+ elif basis in Rings().Commutative():
3559
+ category = category.Commutative()
3560
+
3561
+ if base_ring.is_zero():
3562
+ category = category.Finite()
3563
+ else:
3564
+ category = category.Infinite()
3565
+ Parent.__init__(self, base=base_ring, category=category)
3566
+ self._sparse = sparse
3567
+ self._laurent_poly_ring = basis
3568
+ self._internal_poly_ring = PolynomialRing(self._laurent_poly_ring, "DUMMY_VARIABLE", sparse=sparse)
3569
+
3570
+ def _repr_(self):
3571
+ """
3572
+ String representation of the lazy symmetric functions ring.
3573
+
3574
+ EXAMPLES::
3575
+
3576
+ sage: s = SymmetricFunctions(GF(2)).s() # needs sage.combinat sage.modules
3577
+ sage: LazySymmetricFunctions(s) # needs sage.combinat sage.modules
3578
+ Lazy completion of Symmetric Functions over Finite Field of size 2 in the Schur basis
3579
+ """
3580
+ return "Lazy completion of {}".format(self._laurent_poly_ring)
3581
+
3582
+ def _latex_(self):
3583
+ r"""
3584
+ Return a latex representation of ``self``.
3585
+
3586
+ EXAMPLES::
3587
+
3588
+ sage: s = SymmetricFunctions(GF(2)).s() # needs sage.combinat sage.modules
3589
+ sage: L = LazySymmetricFunctions(s) # needs sage.combinat sage.modules
3590
+ sage: latex(L) # needs sage.combinat sage.modules
3591
+ \text{\texttt{Symmetric{ }Functions{ }over{ }Finite{ }Field{ }of{ }size{ }2{ }in{ }the{ }Schur{ }basis}}
3592
+ """
3593
+ from sage.misc.latex import latex
3594
+ return latex(self._laurent_poly_ring)
3595
+
3596
+ def _monomial(self, c, n):
3597
+ r"""
3598
+ Return the interpretation of the coefficient ``c`` at index ``n``.
3599
+
3600
+ EXAMPLES::
3601
+
3602
+ sage: # needs sage.combinat sage.modules
3603
+ sage: m = SymmetricFunctions(ZZ).m()
3604
+ sage: s = SymmetricFunctions(ZZ).s()
3605
+ sage: L = LazySymmetricFunctions(m)
3606
+ sage: L._monomial(s[2,1], 3)
3607
+ 2*m[1, 1, 1] + m[2, 1]
3608
+ """
3609
+ L = self._laurent_poly_ring
3610
+ return L(c)
3611
+
3612
+ @cached_method
3613
+ def _terms_of_degree(self, n, R):
3614
+ r"""
3615
+ Return the list of basis elements of degree ``n``.
3616
+
3617
+ EXAMPLES::
3618
+
3619
+ sage: # needs sage.combinat sage.modules
3620
+ sage: s = SymmetricFunctions(ZZ).s()
3621
+ sage: L = LazySymmetricFunctions(s)
3622
+ sage: m = L._terms_of_degree(3, QQ["x"]); m
3623
+ [s[3], s[2, 1], s[1, 1, 1]]
3624
+ sage: m[0].parent()
3625
+ Symmetric Functions over Univariate Polynomial Ring in x over Rational Field in the Schur basis
3626
+ sage: L = LazySymmetricFunctions(tensor([s, s]))
3627
+ sage: m = L._terms_of_degree(3, QQ["x"]); m
3628
+ [s[3] # s[],
3629
+ s[2, 1] # s[],
3630
+ s[1, 1, 1] # s[],
3631
+ s[2] # s[1],
3632
+ s[1, 1] # s[1],
3633
+ s[1] # s[2],
3634
+ s[1] # s[1, 1],
3635
+ s[] # s[3],
3636
+ s[] # s[2, 1],
3637
+ s[] # s[1, 1, 1]]
3638
+ sage: m[0].parent()
3639
+ Symmetric Functions over Univariate Polynomial Ring in x over Rational Field in the Schur basis
3640
+ # Symmetric Functions over Univariate Polynomial Ring in x over Rational Field in the Schur basis
3641
+ """
3642
+ from sage.combinat.integer_vector import IntegerVectors
3643
+ from sage.misc.mrange import cartesian_product_iterator
3644
+ from sage.categories.tensor import tensor
3645
+ B = self._internal_poly_ring.base_ring()
3646
+ B = B.change_ring(R)
3647
+ if self._arity == 1:
3648
+ return list(B.homogeneous_component_basis(n))
3649
+
3650
+ return [tensor(m)
3651
+ for c in IntegerVectors(n, self._arity)
3652
+ for m in cartesian_product_iterator([F.homogeneous_component_basis(p)
3653
+ for F, p in zip(B.tensor_factors(), c)])]
3654
+
3655
+ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=None, check=True):
3656
+ r"""
3657
+ Construct a lazy element in ``self`` from ``x``.
3658
+
3659
+ INPUT:
3660
+
3661
+ - ``x`` -- data used to the define a lazy element
3662
+ - ``valuation`` -- integer (optional); a lower bound for the valuation
3663
+ of the series
3664
+ - ``degree`` -- (optional) the degree when the lazy element
3665
+ has finite support
3666
+ - ``check`` -- (optional) check that coefficients are homogeneous of
3667
+ the correct degree when they are retrieved
3668
+
3669
+ EXAMPLES::
3670
+
3671
+ sage: # needs sage.combinat sage.modules
3672
+ sage: m = SymmetricFunctions(GF(2)).m()
3673
+ sage: L = LazySymmetricFunctions(m)
3674
+ sage: L(2)
3675
+ 0
3676
+ sage: L(3)
3677
+ m[]
3678
+
3679
+ sage: # needs sage.combinat sage.modules
3680
+ sage: m = SymmetricFunctions(ZZ).m()
3681
+ sage: L = LazySymmetricFunctions(m)
3682
+ sage: f = L(lambda i: m([i]), valuation=5, degree=10); f
3683
+ m[5] + m[6] + m[7] + m[8] + m[9]
3684
+ sage: f.coefficient(6)
3685
+ m[6]
3686
+ sage: f[20]
3687
+ 0
3688
+
3689
+ Alternatively, ``x`` can be a list of elements of the base ring.
3690
+ Then these elements are read as coefficients of the terms of
3691
+ degrees starting from the ``valuation``::
3692
+
3693
+ sage: f = L([m[1],m[2],m[3]], valuation=1); f # needs sage.combinat sage.modules
3694
+ m[1] + m[2] + m[3]
3695
+
3696
+ Finally, ``x`` can be a symmetric function::
3697
+
3698
+ sage: # needs sage.combinat sage.modules
3699
+ sage: m = SymmetricFunctions(ZZ).m()
3700
+ sage: s = SymmetricFunctions(ZZ).s()
3701
+ sage: L = LazySymmetricFunctions(m)
3702
+ sage: L(s.an_element())
3703
+ 2*m[] + 2*m[1] + (3*m[1,1]+3*m[2])
3704
+
3705
+ TESTS::
3706
+
3707
+ sage: # needs sage.combinat sage.modules
3708
+ sage: e = SymmetricFunctions(ZZ).e()
3709
+ sage: h = SymmetricFunctions(ZZ).h()
3710
+ sage: L = LazySymmetricFunctions(tensor([h, e]))
3711
+ sage: L(lambda n: 0)
3712
+ O^7
3713
+
3714
+ sage: # needs sage.combinat sage.modules
3715
+ sage: L(lambda n: tensor([h[n], e([])]) + tensor([h([]), e[n]]), degree=3)
3716
+ (2*h[]#e[]) + (h[]#e[1]+h[1]#e[]) + (h[]#e[2]+h[2]#e[])
3717
+ sage: L(lambda n: n)[3];
3718
+ Traceback (most recent call last):
3719
+ ...
3720
+ ValueError: coefficient 3*h[] # e[] should be an element
3721
+ of homogeneous degree 3 but has degree 0
3722
+ sage: L([1, 2, 3]);
3723
+ Traceback (most recent call last):
3724
+ ...
3725
+ ValueError: coefficient 2*h[] # e[] should be an element
3726
+ of homogeneous degree 1 but has degree 0
3727
+ sage: L(lambda n: n, degree=3);
3728
+ Traceback (most recent call last):
3729
+ ...
3730
+ ValueError: coefficient h[] # e[] should be an element
3731
+ of homogeneous degree 1 but has degree 0
3732
+ """
3733
+ if valuation is None:
3734
+ valuation = 0
3735
+ if valuation < 0:
3736
+ raise ValueError("the valuation of a lazy completion element must be nonnegative")
3737
+
3738
+ R = self._laurent_poly_ring
3739
+ if x is None:
3740
+ assert degree is None
3741
+ coeff_stream = Stream_uninitialized(valuation)
3742
+ return self.element_class(self, coeff_stream)
3743
+ try:
3744
+ # Try to build stuff using the polynomial ring constructor
3745
+ x = R(x)
3746
+ except (TypeError, ValueError, NotImplementedError):
3747
+ pass
3748
+ if x in R:
3749
+ if not x:
3750
+ coeff_stream = Stream_zero()
3751
+ else:
3752
+ p_dict = {}
3753
+ if self._arity == 1:
3754
+ for f in x.terms():
3755
+ d = f.degree()
3756
+ p_dict[d] = p_dict.get(d, 0) + f
3757
+ else:
3758
+ for f in x.terms():
3759
+ try:
3760
+ d = f.degree()
3761
+ except (TypeError, ValueError, AttributeError):
3762
+ # FIXME: Fallback for symmetric functions in multiple variables
3763
+ d = sum(sum(mu.size() for mu in p) for p in f.support())
3764
+ p_dict[d] = p_dict.get(d, 0) + f
3765
+ v = min(p_dict)
3766
+ d = max(p_dict)
3767
+ p_list = [p_dict.get(i, 0) for i in range(v, d + 1)]
3768
+
3769
+ coeff_stream = Stream_exact(p_list,
3770
+ order=v,
3771
+ constant=self.base_ring().zero(),
3772
+ degree=degree)
3773
+ return self.element_class(self, coeff_stream)
3774
+
3775
+ if isinstance(x, self.Element):
3776
+ return self.element_class(self, x._coeff_stream)
3777
+
3778
+ if self._arity == 1:
3779
+ def check_homogeneous_of_degree(f, d):
3780
+ if not f:
3781
+ return
3782
+ try:
3783
+ d1 = f.homogeneous_degree()
3784
+ if d1 == d:
3785
+ return
3786
+ except ValueError:
3787
+ raise ValueError("coefficient %s should be an element of homogeneous degree %s" % (f, d))
3788
+ raise ValueError("coefficient %s should be an element of homogeneous degree %s but has degree %s" % (f, d, d1))
3789
+ else:
3790
+ def check_homogeneous_of_degree(f, d):
3791
+ if not f:
3792
+ return
3793
+ for m in f.monomials():
3794
+ try:
3795
+ d1 = m.degree()
3796
+ except AttributeError:
3797
+ # FIXME: Fallback for symmetric functions in multiple variables
3798
+ for t in m.support():
3799
+ d1 = sum(p.size() for p in t)
3800
+ if d1 != d:
3801
+ raise ValueError("coefficient %s should be an element of homogeneous degree %s but has degree %s" % (f, d, d1))
3802
+ except (TypeError, ValueError):
3803
+ raise ValueError("coefficient %s is not homogeneous")
3804
+ if d1 != d:
3805
+ raise ValueError("coefficient %s should be an element of homogeneous degree %s but has degree %s" % (f, d, d1))
3806
+
3807
+ if isinstance(x, (tuple, list)):
3808
+ if degree is None:
3809
+ degree = valuation + len(x)
3810
+ p = [R(e) for e in x]
3811
+ for i, e in enumerate(p, valuation):
3812
+ check_homogeneous_of_degree(e, i)
3813
+ coeff_stream = Stream_exact(p,
3814
+ order=valuation,
3815
+ constant=self._laurent_poly_ring.zero(),
3816
+ degree=degree)
3817
+ return self.element_class(self, coeff_stream)
3818
+ if callable(x):
3819
+ if degree is not None:
3820
+ p = [R(x(i)) for i in range(valuation, degree)]
3821
+ for i, e in enumerate(p, valuation):
3822
+ check_homogeneous_of_degree(e, i)
3823
+ coeff_stream = Stream_exact(p,
3824
+ order=valuation,
3825
+ constant=self._laurent_poly_ring.zero(),
3826
+ degree=degree)
3827
+ return self.element_class(self, coeff_stream)
3828
+ if check:
3829
+ def y(n):
3830
+ e = R(x(n))
3831
+ check_homogeneous_of_degree(e, n)
3832
+ return e
3833
+
3834
+ coeff_stream = Stream_function(y, self._sparse, valuation)
3835
+ else:
3836
+ coeff_stream = Stream_function(x, self._sparse, valuation)
3837
+ return self.element_class(self, coeff_stream)
3838
+ raise ValueError(f"unable to convert {x} into a lazy completion element")
3839
+
3840
+ def _an_element_(self):
3841
+ """
3842
+ Return a lazy symmetric function in ``self``.
3843
+
3844
+ EXAMPLES::
3845
+
3846
+ sage: m = SymmetricFunctions(ZZ).m() # needs sage.combinat sage.modules
3847
+ sage: L = LazySymmetricFunctions(m) # needs sage.combinat sage.modules
3848
+ sage: L.an_element() # needs sage.combinat sage.modules
3849
+ 2*m[] + 2*m[1] + 3*m[2]
3850
+ """
3851
+ return self(self._laurent_poly_ring.an_element())
3852
+
3853
+ def some_elements(self):
3854
+ """
3855
+ Return a list of elements of ``self``.
3856
+
3857
+ EXAMPLES::
3858
+
3859
+ sage: m = SymmetricFunctions(GF(5)).m() # needs sage.combinat sage.modules
3860
+ sage: L = LazySymmetricFunctions(m) # needs sage.combinat sage.modules
3861
+ sage: L.some_elements()[:5] # needs sage.combinat sage.modules
3862
+ [0, m[], 2*m[] + 2*m[1] + 3*m[2], 2*m[1] + 3*m[2],
3863
+ 3*m[] + 2*m[1] + (m[1,1]+m[2])
3864
+ + (2*m[1,1,1]+m[3])
3865
+ + (2*m[1,1,1,1]+4*m[2,1,1]+2*m[2,2])
3866
+ + (3*m[2,1,1,1]+3*m[3,1,1]+4*m[3,2]+m[5])
3867
+ + (2*m[2,2,1,1]+m[2,2,2]+2*m[3,2,1]+2*m[3,3]+m[4,1,1]+3*m[4,2]+4*m[5,1]+4*m[6])
3868
+ + O^7]
3869
+
3870
+ sage: # needs sage.combinat sage.modules
3871
+ sage: NCSF = NonCommutativeSymmetricFunctions(QQ)
3872
+ sage: S = NCSF.Complete()
3873
+ sage: L = S.formal_series_ring()
3874
+ sage: L.some_elements()[:4]
3875
+ [0, S[], 2*S[] + 2*S[1] + (3*S[1,1]), 2*S[1] + (3*S[1,1])]
3876
+ """
3877
+ elt = self.an_element()
3878
+ elts = [self.zero(), self.one(), elt]
3879
+ # an element with no constant term
3880
+ elts.append(elt - elt[0])
3881
+ # the inverse of an element
3882
+ try:
3883
+ if elt.is_unit():
3884
+ elts.append(~elt)
3885
+ else:
3886
+ elts.append(~(1 - elt[0] + elt))
3887
+ except NotImplementedError:
3888
+ pass
3889
+ # an element with no constant term and an invertible
3890
+ # coefficient of the linear term
3891
+ it = iter(self._laurent_poly_ring.basis())
3892
+ temp = self.sum(b for _ in range(4) if (b := next(it)).degree())
3893
+ if temp:
3894
+ elts.append(temp)
3895
+
3896
+ return elts
3897
+
3898
+ ######################################################################
3899
+
3900
+
3901
+ class LazySymmetricFunctions(LazyCompletionGradedAlgebra):
3902
+ """
3903
+ The ring of lazy symmetric functions.
3904
+
3905
+ INPUT:
3906
+
3907
+ - ``basis`` -- the ring of symmetric functions
3908
+ - ``names`` -- name(s) of the alphabets
3909
+ - ``sparse`` -- boolean (default: ``True``); whether we use a sparse or a
3910
+ dense representation
3911
+
3912
+ EXAMPLES::
3913
+
3914
+ sage: s = SymmetricFunctions(ZZ).s() # needs sage.combinat sage.modules
3915
+ sage: LazySymmetricFunctions(s) # needs sage.combinat sage.modules
3916
+ Lazy completion of Symmetric Functions over Integer Ring in the Schur basis
3917
+
3918
+ sage: m = SymmetricFunctions(ZZ).m() # needs sage.combinat sage.modules
3919
+ sage: LazySymmetricFunctions(tensor([s, m])) # needs sage.combinat sage.modules
3920
+ Lazy completion of
3921
+ Symmetric Functions over Integer Ring in the Schur basis
3922
+ # Symmetric Functions over Integer Ring in the monomial basis
3923
+ """
3924
+ Element = LazySymmetricFunction
3925
+
3926
+
3927
+ ######################################################################
3928
+
3929
+ class LazyDirichletSeriesRing(LazySeriesRing):
3930
+ r"""
3931
+ The ring of lazy Dirichlet series.
3932
+
3933
+ INPUT:
3934
+
3935
+ - ``base_ring`` -- base ring of this Dirichlet series ring
3936
+ - ``names`` -- name of the generator of this Dirichlet series ring
3937
+ - ``sparse`` -- boolean (default: ``True``); whether this series is sparse or not
3938
+
3939
+ Unlike formal univariate Laurent/power series (over a field),
3940
+ the ring of formal Dirichlet series is not a
3941
+ :wikipedia:`discrete_valuation_ring`. On the other hand, it
3942
+ is a :wikipedia:`local_ring`. The unique maximal ideal
3943
+ consists of all non-invertible series, i.e., series with
3944
+ vanishing constant term.
3945
+
3946
+ .. TODO::
3947
+
3948
+ According to the answers in
3949
+ https://mathoverflow.net/questions/5522/dirichlet-series-with-integer-coefficients-as-a-ufd,
3950
+ (which, in particular, references :arxiv:`math/0105219`)
3951
+ the ring of formal Dirichlet series is actually a
3952
+ :wikipedia:`Unique_factorization_domain` over `\ZZ`.
3953
+
3954
+ .. NOTE::
3955
+
3956
+ An interesting valuation is described in Emil Daniel
3957
+ Schwab; Gheorghe Silberberg *A note on some discrete
3958
+ valuation rings of arithmetical functions*, Archivum
3959
+ Mathematicum, Vol. 36 (2000), No. 2, 103-109,
3960
+ http://dml.cz/dmlcz/107723. Let `J_k` be the ideal of
3961
+ Dirichlet series whose coefficient `f[n]` of `n^s`
3962
+ vanishes if `n` has less than `k` prime factors, counting
3963
+ multiplicities. For any Dirichlet series `f`, let `D(f)`
3964
+ be the largest integer `k` such that `f` is in `J_k`.
3965
+ Then `D` is surjective, `D(f g) = D(f) + D(g)` for
3966
+ nonzero `f` and `g`, and `D(f + g) \geq \min(D(f), D(g))`
3967
+ provided that `f + g` is nonzero.
3968
+
3969
+ For example, `J_1` are series with no constant term, and
3970
+ `J_2` are series such that `f[1]` and `f[p]` for prime
3971
+ `p` vanish.
3972
+
3973
+ Since this is a chain of increasing ideals, the ring of
3974
+ formal Dirichlet series is not a
3975
+ :wikipedia:`Noetherian_ring`.
3976
+
3977
+ Evidently, this valuation cannot be computed for a given
3978
+ series.
3979
+
3980
+ EXAMPLES::
3981
+
3982
+ sage: LazyDirichletSeriesRing(ZZ, 't')
3983
+ Lazy Dirichlet Series Ring in t over Integer Ring
3984
+
3985
+ The ideal generated by `2^-s` and `3^-s` is not principal::
3986
+
3987
+ sage: L = LazyDirichletSeriesRing(QQ, 's')
3988
+ sage: L in PrincipalIdealDomains
3989
+ False
3990
+ """
3991
+ Element = LazyDirichletSeries
3992
+
3993
+ # Follow the "generic" normalization
3994
+ __classcall_private__ = LazySeriesRing.__classcall_private__
3995
+
3996
+ @lazy_attribute
3997
+ def _laurent_poly_ring(self):
3998
+ r"""
3999
+ Return the symbolic ring.
4000
+
4001
+ .. TODO::
4002
+
4003
+ It would be good to have something better than the symbolic ring.
4004
+
4005
+ TESTS::
4006
+
4007
+ sage: L = LazyDirichletSeriesRing(ZZ, 't')
4008
+ sage: L._laurent_poly_ring is SR # needs sage.symbolic
4009
+ True
4010
+ """
4011
+ from sage.symbolic.ring import SR
4012
+ return SR
4013
+
4014
+ def __init__(self, base_ring, names, sparse=True, category=None):
4015
+ r"""
4016
+ Initialize the ring.
4017
+
4018
+ TESTS::
4019
+
4020
+ sage: LazyDirichletSeriesRing.options.halting_precision(12)
4021
+
4022
+ sage: L = LazyDirichletSeriesRing(ZZ, 't')
4023
+ sage: TestSuite(L).run() # needs sage.symbolic
4024
+
4025
+ sage: L = LazyDirichletSeriesRing(QQ, 't')
4026
+ sage: TestSuite(L).run() # needs sage.symbolic
4027
+
4028
+ sage: LazyDirichletSeriesRing.options._reset() # reset the options
4029
+ """
4030
+ if base_ring.characteristic() > 0:
4031
+ raise ValueError("positive characteristic not allowed for Dirichlet series")
4032
+
4033
+ self._sparse = sparse
4034
+ self._minimal_valuation = 1
4035
+ self._arity = 1
4036
+ self._internal_poly_ring = PolynomialRing(base_ring, names, sparse=sparse)
4037
+
4038
+ category = Algebras(base_ring.category())
4039
+ if base_ring in IntegralDomains():
4040
+ category &= IntegralDomains()
4041
+ elif base_ring in Rings().Commutative():
4042
+ category = category.Commutative()
4043
+ category = category.Infinite()
4044
+ Parent.__init__(self, base=base_ring, names=names,
4045
+ category=category)
4046
+
4047
+ def _repr_(self):
4048
+ """
4049
+ String representation of this Dirichlet series ring.
4050
+
4051
+ EXAMPLES::
4052
+
4053
+ sage: LazyDirichletSeriesRing(QQbar, 'z') # needs sage.rings.number_field
4054
+ Lazy Dirichlet Series Ring in z over Algebraic Field
4055
+ """
4056
+ return "Lazy Dirichlet Series Ring in {} over {}".format(self.variable_name(), self.base_ring())
4057
+
4058
+ @cached_method
4059
+ def one(self):
4060
+ r"""
4061
+ Return the constant series `1`.
4062
+
4063
+ EXAMPLES::
4064
+
4065
+ sage: L = LazyDirichletSeriesRing(ZZ, 'z')
4066
+ sage: L.one() # needs sage.symbolic
4067
+ 1
4068
+ sage: ~L.one() # needs sage.symbolic
4069
+ 1 + O(1/(8^z))
4070
+ """
4071
+ R = self.base_ring()
4072
+ coeff_stream = Stream_exact([R.one()], constant=R.zero(), order=1)
4073
+ return self.element_class(self, coeff_stream)
4074
+
4075
+ def _coerce_map_from_(self, S):
4076
+ """
4077
+ Return ``True`` if a coercion from ``S`` exists.
4078
+
4079
+ EXAMPLES::
4080
+
4081
+ sage: L = LazyDirichletSeriesRing(ZZ, 'z')
4082
+ sage: L.has_coerce_map_from(ZZ)
4083
+ True
4084
+ sage: L.has_coerce_map_from(QQ)
4085
+ False
4086
+ """
4087
+ if self.base_ring().has_coerce_map_from(S):
4088
+ return True
4089
+ return False
4090
+
4091
+ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=None, coefficients=None):
4092
+ r"""
4093
+ Construct a Dirichlet series from ``x``.
4094
+
4095
+ INPUT:
4096
+
4097
+ - ``x`` -- data used to the define a Dirichlet series
4098
+ - ``valuation`` -- integer (optional); a lower bound for the exp of the
4099
+ valuation of the series
4100
+ - ``degree`` -- (optional) the degree when the series is ``constant``
4101
+ - ``constant`` -- (optional) the eventual constant of the series
4102
+
4103
+ EXAMPLES::
4104
+
4105
+ sage: L = LazyDirichletSeriesRing(ZZ, 'z')
4106
+ sage: R = L(3)
4107
+ sage: R # needs sage.symbolic
4108
+ 3
4109
+ sage: S = L(lambda i: i, constant=1, degree=6)
4110
+ sage: S # needs sage.symbolic
4111
+ 1 + 2/2^z + 3/3^z + 4/4^z + 5/5^z + 1/(6^z) + 1/(7^z) + 1/(8^z) + O(1/(9^z))
4112
+
4113
+ sage: X = L(constant=5, degree=3)
4114
+ sage: X # needs sage.symbolic
4115
+ 5/3^z + 5/4^z + 5/5^z + O(1/(6^z))
4116
+ sage: X.valuation() # needs sage.symbolic
4117
+ log(3)
4118
+ sage: e = L(moebius)
4119
+ sage: e # needs sage.symbolic
4120
+ 1 - 1/(2^z) - 1/(3^z) - 1/(5^z) + 1/(6^z) - 1/(7^z) + O(1/(8^z))
4121
+
4122
+ sage: T = L([0], constant=1)
4123
+ sage: T # needs sage.symbolic
4124
+ 1/(2^z) + 1/(3^z) + 1/(4^z) + O(1/(5^z))
4125
+
4126
+ sage: U = L(constant=1)
4127
+ sage: U # needs sage.symbolic
4128
+ 1 + 1/(2^z) + 1/(3^z) + O(1/(4^z))
4129
+
4130
+ sage: V = L(lambda i: i, valuation=3)
4131
+ sage: V # needs sage.symbolic
4132
+ 3/3^z + 4/4^z + 5/5^z + 6/6^z + 7/7^z + 8/8^z + 9/9^z + O(1/(10^z))
4133
+
4134
+ Alternatively, ``x`` can be a list of elements of the base ring.
4135
+ Then these elements are read as coefficients of the terms of
4136
+ degrees starting from the ``valuation``. In this case, ``constant``
4137
+ may be just an element of the base ring instead of a tuple or can be
4138
+ simply omitted if it is zero::
4139
+
4140
+ sage: f = L([1,2,3,4], 4)
4141
+ sage: f # needs sage.symbolic
4142
+ 1/(4^z) + 2/5^z + 3/6^z + 4/7^z
4143
+ sage: g = L([1,3,5,7,9], 6, constant=-1)
4144
+ sage: g # needs sage.symbolic
4145
+ 1/(6^z) + 3/7^z + 5/8^z + 7/9^z + 9/10^z - 1/(11^z) - 1/(12^z)
4146
+ - 1/(13^z) + O(1/(14^z))
4147
+
4148
+ TESTS::
4149
+
4150
+ sage: L = LazyDirichletSeriesRing(GF(2), 'z')
4151
+ Traceback (most recent call last):
4152
+ ...
4153
+ ValueError: positive characteristic not allowed for Dirichlet series
4154
+
4155
+ sage: L.<z> = LazyLaurentSeriesRing(QQ)
4156
+ sage: D = LazyDirichletSeriesRing(QQ, 't')
4157
+ sage: d = D(L.one()) # needs sage.symbolic
4158
+ sage: d # needs sage.symbolic
4159
+ 1 + 1/(2^t) + 1/(3^t) + 1/(4^t) + 1/(5^t) + 1/(6^t) + 1/(7^t) + O(1/(8^t))
4160
+
4161
+ sage: R.<z> = LaurentPolynomialRing(QQ)
4162
+ sage: D = LazyDirichletSeriesRing(QQ, 't')
4163
+ sage: dd = D(coefficients=z + z^2)
4164
+ sage: dd # needs sage.symbolic
4165
+ 2 + 6/2^t + 12/3^t + 20/4^t + 30/5^t + 42/6^t + 56/7^t + O(1/(8^t))
4166
+
4167
+ sage: s = D(lambda n: n)
4168
+ sage: d2 = D(s, valuation=2) # needs sage.symbolic
4169
+ sage: d2 # needs sage.symbolic
4170
+ 1/(2^t) + 2/3^t + 3/4^t + 4/5^t + 5/6^t + 6/7^t + 7/8^t + O(1/(9^t))
4171
+
4172
+ sage: Ds = LazyDirichletSeriesRing(ZZ, 's')
4173
+ sage: m = Ds(moebius, valuation=2)
4174
+ sage: m # needs sage.symbolic
4175
+ -1/(2^s) - 1/(3^s) - 1/(5^s) + 1/(6^s) - 1/(7^s) + O(1/(9^s))
4176
+ sage: D = LazyDirichletSeriesRing(QQ, 't')
4177
+ sage: dm = D(m) # needs sage.libs.pari sage.symbolic
4178
+ sage: dm # needs sage.libs.pari sage.symbolic
4179
+ -1/(2^t) - 1/(3^t) - 1/(5^t) + 1/(6^t) - 1/(7^t) + O(1/(9^t))
4180
+ """
4181
+ if isinstance(x, (list, tuple)):
4182
+ p = self._internal_poly_ring(x)
4183
+ if valuation is None:
4184
+ if not p:
4185
+ valuation = 1 + len(x)
4186
+ x = p
4187
+ else:
4188
+ x = p.shift(1)
4189
+ else:
4190
+ if coefficients is not None:
4191
+ if valuation is None:
4192
+ valuation = 1
4193
+ return super()._element_constructor_(x, valuation, degree, constant, coefficients)
4194
+
4195
+ BR = self.base_ring()
4196
+ if x in BR:
4197
+ if valuation is None:
4198
+ valuation = 1
4199
+ x = BR(x)
4200
+
4201
+ elif not isinstance(x, LazyDirichletSeries):
4202
+ if valuation is None:
4203
+ valuation = 1
4204
+
4205
+ if isinstance(x, LazyModuleElement) or callable(x):
4206
+ if coefficients is not None:
4207
+ raise ValueError("coefficients must be None if x is provided")
4208
+ coefficients = x
4209
+ x = None
4210
+
4211
+ if valuation is not None and (valuation not in ZZ or valuation <= 0):
4212
+ raise ValueError("the valuation must be a positive integer")
4213
+
4214
+ return super()._element_constructor_(x, valuation, degree, constant, coefficients)
4215
+
4216
+ def _an_element_(self):
4217
+ """
4218
+ Return a Dirichlet series in this ring.
4219
+
4220
+ EXAMPLES::
4221
+
4222
+ sage: L = LazyDirichletSeriesRing(ZZ, 'z')
4223
+ sage: m = L.an_element()
4224
+ sage: m # needs sage.symbolic
4225
+ 1/(4^z) + 1/(5^z) + 1/(6^z) + O(1/(7^z))
4226
+ """
4227
+ c = self.base_ring().an_element()
4228
+ return self.element_class(self, Stream_exact([], constant=c, order=4))
4229
+
4230
+ def some_elements(self):
4231
+ """
4232
+ Return a list of elements of ``self``.
4233
+
4234
+ EXAMPLES::
4235
+
4236
+ sage: L = LazyDirichletSeriesRing(ZZ, 'z')
4237
+ sage: l = L.some_elements()
4238
+ sage: l # needs sage.symbolic
4239
+ [0, 1,
4240
+ 1/(4^z) + 1/(5^z) + 1/(6^z) + O(1/(7^z)),
4241
+ 1/(2^z) - 1/(3^z) + 2/4^z - 2/5^z + 3/6^z - 3/7^z + 4/8^z - 4/9^z,
4242
+ 1/(2^z) - 1/(3^z) + 2/4^z - 2/5^z + 3/6^z - 3/7^z + 4/8^z - 4/9^z + 1/(10^z) + 1/(11^z) + 1/(12^z) + O(1/(13^z)),
4243
+ 1 + 4/2^z + 9/3^z + 16/4^z + 25/5^z + 36/6^z + 49/7^z + O(1/(8^z))]
4244
+
4245
+ sage: L = LazyDirichletSeriesRing(QQ, 'z')
4246
+ sage: l = L.some_elements()
4247
+ sage: l # needs sage.symbolic
4248
+ [0, 1,
4249
+ 1/2/4^z + 1/2/5^z + 1/2/6^z + O(1/(7^z)),
4250
+ 1/2 - 1/2/2^z + 2/3^z - 2/4^z + 1/(6^z) - 1/(7^z) + 42/8^z + 2/3/9^z,
4251
+ 1/2 - 1/2/2^z + 2/3^z - 2/4^z + 1/(6^z) - 1/(7^z) + 42/8^z + 2/3/9^z + 1/2/10^z + 1/2/11^z + 1/2/12^z + O(1/(13^z)),
4252
+ 1 + 4/2^z + 9/3^z + 16/4^z + 25/5^z + 36/6^z + 49/7^z + O(1/(8^z))]
4253
+ """
4254
+ R = self.base_ring()
4255
+ some_numbers = [c for c, _ in zip(R.some_elements(), range(9))]
4256
+ elts = [self.zero(), self.one(), self.an_element(),
4257
+ self(some_numbers),
4258
+ self(some_numbers, constant=R.an_element()),
4259
+ self(lambda n: n**2)]
4260
+ return elts
4261
+
4262
+ def _monomial(self, c, n):
4263
+ r"""
4264
+ Return the interpretation of the coefficient ``c`` at index ``n``.
4265
+
4266
+ EXAMPLES::
4267
+
4268
+ sage: L = LazyDirichletSeriesRing(ZZ, 'z')
4269
+ sage: m = L._monomial(5, 3); m # needs sage.symbolic
4270
+ 5/3^z
4271
+ """
4272
+ try:
4273
+ L = self._laurent_poly_ring
4274
+ return L(c) * L(n) ** -L(self.variable_name())
4275
+ except (ValueError, TypeError):
4276
+ return '({})/{}^{}'.format(self.base_ring()(c), n, self.variable_name())
4277
+
4278
+ def _terms_of_degree(self, n, R):
4279
+ r"""
4280
+ Return the list consisting of a single element 1 in the base ring.
4281
+
4282
+ EXAMPLES::
4283
+
4284
+ sage: L = LazyDirichletSeriesRing(ZZ, 'z')
4285
+ sage: t = L._terms_of_degree(3, ZZ['x']); t
4286
+ [1]
4287
+ sage: t[0].parent()
4288
+ Univariate Polynomial Ring in x over Integer Ring
4289
+ """
4290
+ return [R.one()]
4291
+
4292
+ def polylogarithm(self, z):
4293
+ r"""
4294
+ Return the polylogarithm at `z` considered as a Dirichlet series
4295
+ in ``self``.
4296
+
4297
+ The *polylogarithm* at `z` is the Dirichlet series
4298
+
4299
+ .. MATH::
4300
+
4301
+ \mathrm{Li}_s(z) = \sum_{k=1}^{\infty} \frac{z^k}{k^s}.
4302
+
4303
+ EXAMPLES::
4304
+
4305
+ sage: # needs sage.symbolic
4306
+ sage: R.<z> = ZZ[]
4307
+ sage: L = LazyDirichletSeriesRing(R, 's')
4308
+ sage: L.polylogarithm(z)
4309
+ z + z^2/2^s + z^3/3^s + z^4/4^s + z^5/5^s + z^6/6^s + z^7/7^s + O(1/(8^s))
4310
+
4311
+ At `z = 1`, this is the Riemann zeta function::
4312
+
4313
+ sage: L.polylogarithm(1) # needs sage.symbolic
4314
+ 1 + 1/(2^s) + 1/(3^s) + 1/(4^s) + 1/(5^s) + 1/(6^s) + 1/(7^s) + O(1/(8^s))
4315
+
4316
+ At `z = -1`, this is the negative of the Dirichlet eta function::
4317
+
4318
+ sage: -L.polylogarithm(-1) # needs sage.symbolic
4319
+ 1 - 1/(2^s) + 1/(3^s) - 1/(4^s) + 1/(5^s) - 1/(6^s) + 1/(7^s) + O(1/(8^s))
4320
+
4321
+ REFERENCES:
4322
+
4323
+ - :wikipedia:`Polylogarithm`
4324
+ """
4325
+ if self._arity != 1:
4326
+ raise ValueError("must has arity 1")
4327
+ return self(coefficients=lambda n: z ** n)
4328
+
4329
+ polylog = polylogarithm
4330
+
4331
+
4332
+ def _skip_leading_zeros(iterator):
4333
+ """
4334
+ Return an iterator which discards all leading zeros.
4335
+
4336
+ EXAMPLES::
4337
+
4338
+ sage: from sage.rings.lazy_series_ring import _skip_leading_zeros
4339
+ sage: it = map(lambda x: 0 if x < 10 else x, NN)
4340
+ sage: [x for x, _ in zip(_skip_leading_zeros(it), range(10))]
4341
+ [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
4342
+
4343
+ sage: # needs sage.rings.finite_rings
4344
+ sage: it = map(GF(3), NN)
4345
+ sage: [x for x, _ in zip(it, range(10))]
4346
+ [0, 1, 2, 0, 1, 2, 0, 1, 2, 0]
4347
+ sage: it = map(GF(3), NN)
4348
+ sage: [x for x, _ in zip(_skip_leading_zeros(it), range(10))]
4349
+ [1, 2, 0, 1, 2, 0, 1, 2, 0, 1]
4350
+ """
4351
+ while True:
4352
+ c = next(iterator)
4353
+ if c:
4354
+ yield c
4355
+ break
4356
+ yield from iterator