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,1505 @@
1
+ # sage_setup: distribution = sagemath-categories
2
+ # sage.doctest: needs sage.symbolic
3
+ r"""
4
+ Piecewise functions
5
+
6
+ This module implement piecewise functions in a single variable. See
7
+ :mod:`sage.sets.real_set` for more information about how to construct
8
+ subsets of the real line for the domains.
9
+
10
+ EXAMPLES::
11
+
12
+ sage: f = piecewise([((0,1), x^3), ([-1,0], -x^2)]); f
13
+ piecewise(x|-->x^3 on (0, 1), x|-->-x^2 on [-1, 0]; x)
14
+ sage: 2*f
15
+ 2*piecewise(x|-->x^3 on (0, 1), x|-->-x^2 on [-1, 0]; x)
16
+ sage: f(x=1/2)
17
+ 1/8
18
+ sage: plot(f) # not tested
19
+
20
+ .. TODO::
21
+
22
+ Implement max/min location and values,
23
+
24
+ AUTHORS:
25
+
26
+ - David Joyner (2006-04): initial version
27
+
28
+ - David Joyner (2006-09): added __eq__, extend_by_zero_to, unextend,
29
+ convolution, trapezoid, trapezoid_integral_approximation,
30
+ riemann_sum, riemann_sum_integral_approximation, tangent_line fixed
31
+ bugs in __mul__, __add__
32
+
33
+ - David Joyner (2007-03): adding Hann filter for FS, added general FS
34
+ filter methods for computing and plotting, added options to plotting
35
+ of FS (eg, specifying rgb values are now allowed). Fixed bug in
36
+ documentation reported by Pablo De Napoli.
37
+
38
+ - David Joyner (2007-09): bug fixes due to behaviour of
39
+ SymbolicArithmetic
40
+
41
+ - David Joyner (2008-04): fixed docstring bugs reported by J Morrow; added
42
+ support for Laplace transform of functions with infinite support.
43
+
44
+ - David Joyner (2008-07): fixed a left multiplication bug reported by
45
+ C. Boncelet (by defining __rmul__ = __mul__).
46
+
47
+ - Paul Butler (2009-01): added indefinite integration and default_variable
48
+
49
+ - Volker Braun (2013): Complete rewrite
50
+
51
+ - Ralf Stephan (2015): Rewrite of convolution() and other calculus
52
+ functions; many doctest adaptations
53
+
54
+ - Eric Gourgoulhon (2017): Improve documentation and user interface of
55
+ Fourier series
56
+
57
+ TESTS::
58
+
59
+ sage: fast_callable(f, vars=[x])(0.5)
60
+ 0.125000000000...
61
+ """
62
+
63
+ # ****************************************************************************
64
+ # Copyright (C) 2006 William Stein <wstein@gmail.com>
65
+ # 2006 David Joyner <wdjoyner@gmail.com>
66
+ # 2013 Volker Braun <vbraun.name@gmail.com>
67
+ #
68
+ # This program is free software: you can redistribute it and/or modify
69
+ # it under the terms of the GNU General Public License as published by
70
+ # the Free Software Foundation, either version 2 of the License, or
71
+ # (at your option) any later version.
72
+ # https://www.gnu.org/licenses/
73
+ # ****************************************************************************
74
+
75
+ from sage.misc.lazy_import import lazy_import
76
+ from sage.rings.infinity import minus_infinity, infinity
77
+ from sage.sets.real_set import RealSet
78
+ from sage.symbolic.function import BuiltinFunction
79
+
80
+ lazy_import('sage.symbolic.ring', 'SR')
81
+
82
+
83
+ class PiecewiseFunction(BuiltinFunction):
84
+ def __init__(self):
85
+ """
86
+ Piecewise function.
87
+
88
+ EXAMPLES::
89
+
90
+ sage: var('x, y')
91
+ (x, y)
92
+ sage: f = piecewise([((0,1), x^2*y), ([-1,0], -x*y^2)], var=x); f
93
+ piecewise(x|-->x^2*y on (0, 1), x|-->-x*y^2 on [-1, 0]; x)
94
+ sage: f(1/2)
95
+ 1/4*y
96
+ sage: f(-1/2)
97
+ 1/2*y^2
98
+ """
99
+ BuiltinFunction.__init__(self, "piecewise",
100
+ latex_name='piecewise',
101
+ conversions=dict(), nargs=2)
102
+
103
+ def __call__(self, function_pieces, **kwds):
104
+ r"""
105
+ Piecewise functions.
106
+
107
+ INPUT:
108
+
109
+ - ``function_pieces`` -- list of pairs consisting of a
110
+ domain and a symbolic function
111
+
112
+ - ``var=x`` -- a symbolic variable or ``None`` (default); the
113
+ real variable in which the function is piecewise in
114
+
115
+ OUTPUT:
116
+
117
+ A piecewise-defined function. A :exc:`ValueError` will be raised
118
+ if the domains of the pieces are not pairwise disjoint.
119
+
120
+ EXAMPLES::
121
+
122
+ sage: my_abs = piecewise([((-1, 0), -x), ([0, 1], x)], var=x); my_abs
123
+ piecewise(x|-->-x on (-1, 0), x|-->x on [0, 1]; x)
124
+ sage: [ my_abs(i/5) for i in range(-4, 5)]
125
+ [4/5, 3/5, 2/5, 1/5, 0, 1/5, 2/5, 3/5, 4/5]
126
+
127
+ TESTS::
128
+
129
+ sage: piecewise([([-1, 0], -x), ([0, 1], x)], var=x)
130
+ Traceback (most recent call last):
131
+ ...
132
+ ValueError: domains must be pairwise disjoint
133
+
134
+ sage: step = piecewise([((-1, 0), -1), ([0, 0], 0), ((0, 1), 1)], var=x); step
135
+ piecewise(x|-->-1 on (-1, 0), x|-->0 on {0}, x|-->1 on (0, 1); x)
136
+ sage: step(-1/2), step(0), step(1/2)
137
+ (-1, 0, 1)
138
+ """
139
+ from types import FunctionType
140
+ var = kwds.pop('var', None)
141
+ parameters = []
142
+ domain_list = []
143
+ for piece in function_pieces:
144
+ domain, function = piece
145
+ if not isinstance(domain, RealSet):
146
+ domain = RealSet(domain)
147
+ if domain.is_empty():
148
+ continue
149
+ if isinstance(function, FunctionType):
150
+ if var is None:
151
+ var = SR.var('x')
152
+ if function.__code__.co_argcount == 0:
153
+ function = function()
154
+ else:
155
+ function = function(var)
156
+ function = SR(function)
157
+ if var is None and len(function.variables()) > 0:
158
+ var = function.variables()[0]
159
+ parameters.append((domain, function))
160
+ domain_list.append(domain)
161
+ if not RealSet.are_pairwise_disjoint(*domain_list):
162
+ raise ValueError('domains must be pairwise disjoint')
163
+ if var is None:
164
+ var = self.default_variable()
165
+ parameters = SR._force_pyobject(tuple(parameters), recursive=False)
166
+ return BuiltinFunction.__call__(self, parameters, var, **kwds)
167
+
168
+ def _print_(self, parameters, variable):
169
+ """
170
+ Return a string representation.
171
+
172
+ OUTPUT: string
173
+
174
+ EXAMPLES::
175
+
176
+ sage: p = piecewise([((-2, 0), -x), ([0, 4], x)], var=x)
177
+ sage: str(p) # indirect doctest
178
+ 'piecewise(x|-->-x on (-2, 0), x|-->x on [0, 4]; x)'
179
+ """
180
+ s = 'piecewise('
181
+ # NOTE : could use ⟼ instead of |-->
182
+ args = (f'{variable}|-->{func} on {domain}'
183
+ for domain, func in parameters)
184
+ s += ', '.join(args) + f'; {variable})'
185
+ return s
186
+
187
+ def _subs_(self, subs_map, options, parameters, x):
188
+ """
189
+ Callback from Pynac ``subs()``.
190
+
191
+ EXAMPLES:
192
+
193
+ If the substitution changes the piecewise variable, it must
194
+ evaluate to a number so that we know which component we are
195
+ on::
196
+
197
+ sage: p = piecewise([((-2, 0), -x), ([0, 4], x)], var=x)
198
+ sage: p.subs(x=-1)
199
+ 1
200
+ sage: (10+p).subs(x=-1)
201
+ 11
202
+ sage: p.subs(x=pi)
203
+ pi
204
+
205
+ Auxiliary variables can be substituted arbitrarily::
206
+
207
+ sage: var('x,y')
208
+ (x, y)
209
+ sage: p = piecewise([((-2, 0), -x^y), ([0, 2], x-y)], var=x); p
210
+ piecewise(x|-->-x^y on (-2, 0), x|-->x - y on [0, 2]; x)
211
+ sage: p.subs(y=sin(y))
212
+ piecewise(x|-->-x^sin(y) on (-2, 0), x|-->x - sin(y) on [0, 2]; x)
213
+
214
+ One can change the variable as follows::
215
+
216
+ sage: p = piecewise([((-2, 0), -x), ([0, 4], x)], var=x)
217
+ sage: y = SR.var('y')
218
+ sage: p(y)
219
+ piecewise(y|-->-y on (-2, 0), y|-->y on [0, 4]; y)
220
+ """
221
+ point = subs_map.apply_to(x, 0)
222
+
223
+ if point.is_symbol(): # avoid to compare with x (see #37925)
224
+ new_params = [(domain, subs_map.apply_to(func, 0))
225
+ for domain, func in parameters]
226
+ return piecewise(new_params, var=point)
227
+
228
+ if (point.is_numeric() or point.is_constant()) and point.is_real():
229
+ if hasattr(point, 'pyobject'):
230
+ # unwrap any numeric values
231
+ point = point.pyobject()
232
+ for domain, func in parameters:
233
+ if domain.contains(point):
234
+ return subs_map.apply_to(func, 0)
235
+ raise ValueError(f'point {point} is not in the domain')
236
+
237
+ raise ValueError('substitution not allowed')
238
+
239
+ @staticmethod
240
+ def in_operands(ex):
241
+ """
242
+ Return whether a symbolic expression contains a piecewise
243
+ function as operand.
244
+
245
+ INPUT:
246
+
247
+ - ``ex`` -- a symbolic expression
248
+
249
+ OUTPUT: boolean
250
+
251
+ EXAMPLES::
252
+
253
+ sage: f = piecewise([([0,0], sin(x)), ((0,2), cos(x))]); f
254
+ piecewise(x|-->sin(x) on {0}, x|-->cos(x) on (0, 2); x)
255
+ sage: piecewise.in_operands(f)
256
+ True
257
+ sage: piecewise.in_operands(1+sin(f))
258
+ True
259
+ sage: piecewise.in_operands(1+sin(0*f))
260
+ False
261
+ """
262
+ def is_piecewise(ex):
263
+ if ex.operator() is piecewise:
264
+ return True
265
+ for op in ex.operands():
266
+ if is_piecewise(op):
267
+ return True
268
+ return False
269
+ return is_piecewise(ex)
270
+
271
+ @staticmethod
272
+ def simplify(ex):
273
+ """
274
+ Combine piecewise operands into single piecewise function.
275
+
276
+ OUTPUT:
277
+
278
+ A piecewise function whose operands are not piecewise if
279
+ possible, that is, as long as the piecewise variable is the same.
280
+
281
+ EXAMPLES::
282
+
283
+ sage: f = piecewise([([0,0], sin(x)), ((0,2), cos(x))])
284
+ sage: piecewise.simplify(f)
285
+ Traceback (most recent call last):
286
+ ...
287
+ NotImplementedError
288
+ """
289
+ raise NotImplementedError
290
+
291
+ def _tderivative_(self, parameters, variable, *args, **kwds):
292
+ """
293
+ Return the derivative of the piecewise function by applying the
294
+ derivative to each piece.
295
+
296
+ EXAMPLES::
297
+
298
+ sage: f = piecewise([[(-1,1), x**2], [(1,3), x**3]])
299
+ sage: f.diff()
300
+ piecewise(x|-->2*x on (-1, 1), x|-->3*x^2 on (1, 3); x)
301
+ sage: f.diff(x,x)
302
+ piecewise(x|-->2 on (-1, 1), x|-->6*x on (1, 3); x)
303
+
304
+ This still fails miserably::
305
+
306
+ sage: y = SR.var('y')
307
+ sage: f = piecewise([[(-6,0), x+y], [(0,8), x*y]],var=x)
308
+ sage: f.derivative(x) # known bug
309
+ piecewise(x|-->1 on (-6, 0), x|-->y on (0, 8); x)
310
+ sage: f.derivative(y) # known bug
311
+ piecewise(x|-->1 on (-6, 0), x|-->x on (0, 8); x)
312
+
313
+ TESTS::
314
+
315
+ sage: f = piecewise([((-oo, -1), 0), ((-1, 1), exp(-1/(1 - x^2))), ((1, oo), 0)])
316
+ sage: f.diff()
317
+ piecewise(x|-->0 on (-oo, -1), x|-->-2*x*e^(1/(x^2 - 1))/(x^2 - 1)^2 on (-1, 1), x|-->0 on (1, +oo); x)
318
+ """
319
+ return piecewise([(domain, func.derivative(*args))
320
+ for domain, func in parameters],
321
+ var=variable)
322
+
323
+ class EvaluationMethods:
324
+
325
+ def __pow__(self, parameters, variable, n):
326
+ """
327
+ Return the `n`-th power of the piecewise function by applying the
328
+ operation to each piece.
329
+
330
+ INPUT:
331
+
332
+ - ``n`` -- number or symbolic expression
333
+
334
+ EXAMPLES::
335
+
336
+ sage: f1(x) = -abs(x) + 1; f2(x) = abs(x - 2) - 1
337
+ sage: f = piecewise([[(-1,1), f1], [(1,3), f2]])
338
+ sage: (f^2).integral(definite=True)
339
+ 4/3
340
+ """
341
+ return piecewise(zip(self.domains(),
342
+ [ex**n for ex in self.expressions()]),
343
+ var=variable)
344
+
345
+ def expression_at(self, parameters, variable, point):
346
+ """
347
+ Return the expression defining the piecewise function at
348
+ ``value``.
349
+
350
+ INPUT:
351
+
352
+ - ``point`` -- a real number
353
+
354
+ OUTPUT:
355
+
356
+ The symbolic expression defining the function value at the
357
+ given ``point``.
358
+
359
+ EXAMPLES::
360
+
361
+ sage: f = piecewise([([0,0], sin(x)), ((0,2), cos(x))]); f
362
+ piecewise(x|-->sin(x) on {0}, x|-->cos(x) on (0, 2); x)
363
+ sage: f.expression_at(0)
364
+ sin(x)
365
+ sage: f.expression_at(1)
366
+ cos(x)
367
+ sage: f.expression_at(2)
368
+ Traceback (most recent call last):
369
+ ...
370
+ ValueError: point is not in the domain
371
+ """
372
+ for domain, func in parameters:
373
+ if domain.contains(point):
374
+ return func
375
+ raise ValueError('point is not in the domain')
376
+
377
+ which_function = expression_at
378
+
379
+ def domains(self, parameters, variable):
380
+ """
381
+ Return the individual domains.
382
+
383
+ See also :meth:`~expressions`.
384
+
385
+ OUTPUT:
386
+
387
+ The collection of domains of the component functions as a
388
+ tuple of :class:`~sage.sets.real_set.RealSet`.
389
+
390
+ EXAMPLES::
391
+
392
+ sage: f = piecewise([([0,0], sin(x)), ((0,2), cos(x))]); f
393
+ piecewise(x|-->sin(x) on {0}, x|-->cos(x) on (0, 2); x)
394
+ sage: f.domains()
395
+ ({0}, (0, 2))
396
+ """
397
+ return tuple(dom for dom, fun in parameters)
398
+
399
+ def domain(self, parameters, variable):
400
+ """
401
+ Return the domain.
402
+
403
+ OUTPUT:
404
+
405
+ The union of the domains of the individual pieces as a
406
+ :class:`~sage.sets.real_set.RealSet`.
407
+
408
+ EXAMPLES::
409
+
410
+ sage: f = piecewise([([0,0], sin(x)), ((0,2), cos(x))]); f
411
+ piecewise(x|-->sin(x) on {0}, x|-->cos(x) on (0, 2); x)
412
+ sage: f.domain()
413
+ [0, 2)
414
+ """
415
+ intervals = []
416
+ for domain, func in parameters:
417
+ intervals += list(domain)
418
+ return RealSet(*intervals)
419
+
420
+ def __len__(self, parameters, variable):
421
+ """
422
+ Return the number of "pieces".
423
+
424
+ OUTPUT: integer
425
+
426
+ EXAMPLES::
427
+
428
+ sage: f = piecewise([([0,0], sin(x)), ((0,2), cos(x))]); f
429
+ piecewise(x|-->sin(x) on {0}, x|-->cos(x) on (0, 2); x)
430
+ sage: len(f)
431
+ 2
432
+ """
433
+ return len(parameters)
434
+
435
+ def expressions(self, parameters, variable):
436
+ """
437
+ Return the individual domains.
438
+
439
+ See also :meth:`~domains`.
440
+
441
+ OUTPUT: the collection of expressions of the component functions
442
+
443
+ EXAMPLES::
444
+
445
+ sage: f = piecewise([([0,0], sin(x)), ((0,2), cos(x))]); f
446
+ piecewise(x|-->sin(x) on {0}, x|-->cos(x) on (0, 2); x)
447
+ sage: f.expressions()
448
+ (sin(x), cos(x))
449
+ """
450
+ return tuple(fun for dom, fun in parameters)
451
+
452
+ def items(self, parameters, variable):
453
+ """
454
+ Iterate over the pieces of the piecewise function.
455
+
456
+ .. NOTE::
457
+
458
+ You should probably use :meth:`pieces` instead, which
459
+ offers a nicer interface.
460
+
461
+ OUTPUT:
462
+
463
+ This method iterates over pieces of the piecewise
464
+ function, each represented by a pair. The first element is
465
+ the support, and the second the function over that
466
+ support.
467
+
468
+ EXAMPLES::
469
+
470
+ sage: f = piecewise([([0,0], sin(x)), ((0,2), cos(x))])
471
+ sage: for support, function in f.items():
472
+ ....: print('support is {0}, function is {1}'.format(support, function))
473
+ support is {0}, function is sin(x)
474
+ support is (0, 2), function is cos(x)
475
+ """
476
+ yield from parameters
477
+
478
+ def __call__(self, parameters, variable, value=None, **kwds):
479
+ """
480
+ Call the piecewise function.
481
+
482
+ EXAMPLES::
483
+
484
+ sage: f = piecewise([([0,0], sin(x)), ((0,2), cos(x))]); f
485
+ piecewise(x|-->sin(x) on {0}, x|-->cos(x) on (0, 2); x)
486
+ sage: f(0)
487
+ 0
488
+ sage: f(1)
489
+ cos(1)
490
+ sage: f(2)
491
+ Traceback (most recent call last):
492
+ ...
493
+ ValueError: point 2 is not in the domain
494
+ """
495
+ self = piecewise(parameters, var=variable)
496
+ substitution = dict()
497
+ for k, v in kwds.items():
498
+ substitution[SR.var(k)] = v
499
+ if value is not None:
500
+ substitution[variable] = value
501
+ return self.subs(substitution)
502
+
503
+ def _fast_callable_(self, parameters, variable, etb):
504
+ """
505
+ Override the ``fast_callable``.
506
+
507
+ OUTPUT:
508
+
509
+ A :class:`~sage.ext.fast_callable.ExpressionCall`
510
+ representing the piecewise function in the expression
511
+ tree.
512
+
513
+ EXAMPLES::
514
+
515
+ sage: p = piecewise([((-1, 0), -x), ([0, 1], x)], var=x)
516
+ sage: from sage.ext.fast_callable import ExpressionTreeBuilder
517
+ sage: etb = ExpressionTreeBuilder(vars=['x'])
518
+ sage: p._fast_callable_(etb)
519
+ {piecewise(x|-->-x on (-1, 0), x|-->x on [0, 1]; x)}(v_0)
520
+ """
521
+ self = piecewise(parameters, var=variable)
522
+ return etb.call(self, variable)
523
+
524
+ def restriction(self, parameters, variable, restricted_domain):
525
+ """
526
+ Restrict the domain.
527
+
528
+ INPUT:
529
+
530
+ - ``restricted_domain`` -- a
531
+ :class:`~sage.sets.real_set.RealSet` or something that
532
+ defines one.
533
+
534
+ OUTPUT: a new piecewise function obtained by restricting the domain
535
+
536
+ EXAMPLES::
537
+
538
+ sage: f = piecewise([((-oo, oo), x)]); f
539
+ piecewise(x|-->x on (-oo, +oo); x)
540
+ sage: f.restriction([[-1,1], [3,3]])
541
+ piecewise(x|-->x on [-1, 1] ∪ {3}; x)
542
+ """
543
+ restricted_domain = RealSet(*restricted_domain)
544
+ new_param = []
545
+ for domain, func in parameters:
546
+ domain = domain.intersection(restricted_domain)
547
+ new_param.append((domain, func))
548
+ return piecewise(new_param, var=variable)
549
+
550
+ def extension(self, parameters, variable, extension, extension_domain=None):
551
+ """
552
+ Extend the function.
553
+
554
+ INPUT:
555
+
556
+ - ``extension`` -- a symbolic expression
557
+
558
+ - ``extension_domain`` -- a
559
+ :class:`~sage.sets.real_set.RealSet` or ``None``
560
+ (default). The domain of the extension. By default, the
561
+ entire complement of the current domain.
562
+
563
+ EXAMPLES::
564
+
565
+ sage: f = piecewise([((-1,1), x)]); f
566
+ piecewise(x|-->x on (-1, 1); x)
567
+ sage: f(3)
568
+ Traceback (most recent call last):
569
+ ...
570
+ ValueError: point 3 is not in the domain
571
+
572
+ sage: g = f.extension(0); g
573
+ piecewise(x|-->x on (-1, 1), x|-->0 on (-oo, -1] ∪ [1, +oo); x)
574
+ sage: g(3)
575
+ 0
576
+
577
+ sage: h = f.extension(1, RealSet.unbounded_above_closed(1)); h
578
+ piecewise(x|-->x on (-1, 1), x|-->1 on [1, +oo); x)
579
+ sage: h(3)
580
+ 1
581
+ """
582
+ self = piecewise(parameters, var=variable)
583
+ if extension_domain is None:
584
+ extension_domain = self.domain().complement()
585
+ ext = ((extension_domain, SR(extension)),)
586
+ return piecewise(parameters + ext, var=variable)
587
+
588
+ def unextend_zero(self, parameters, variable):
589
+ """
590
+ Remove zero pieces.
591
+
592
+ EXAMPLES::
593
+
594
+ sage: f = piecewise([((-1,1), x)]); f
595
+ piecewise(x|-->x on (-1, 1); x)
596
+ sage: g = f.extension(0); g
597
+ piecewise(x|-->x on (-1, 1), x|-->0 on (-oo, -1] ∪ [1, +oo); x)
598
+ sage: g(3)
599
+ 0
600
+ sage: h = g.unextend_zero()
601
+ sage: bool(h == f)
602
+ True
603
+ """
604
+ result = [(domain, func) for domain, func in parameters
605
+ if func != 0]
606
+ if len(result) == len(self):
607
+ return self
608
+ return piecewise(result, var=variable)
609
+
610
+ def pieces(self, parameters, variable):
611
+ """
612
+ Return the "pieces".
613
+
614
+ OUTPUT:
615
+
616
+ A tuple of piecewise functions, each having only a single
617
+ expression.
618
+
619
+ EXAMPLES::
620
+
621
+ sage: p = piecewise([((-1, 0), -x), ([0, 1], x)], var=x)
622
+ sage: p.pieces()
623
+ (piecewise(x|-->-x on (-1, 0); x),
624
+ piecewise(x|-->x on [0, 1]; x))
625
+ """
626
+ return tuple(piecewise([(domain, func)], var=variable)
627
+ for domain, func in parameters)
628
+
629
+ def end_points(self, parameters, variable) -> list:
630
+ """
631
+ Return a list of all interval endpoints for this function.
632
+
633
+ EXAMPLES::
634
+
635
+ sage: f1(x) = 1
636
+ sage: f2(x) = 1 - x
637
+ sage: f3(x) = x^2 - 5
638
+ sage: f = piecewise([[(0,1), f1], [(1,2), f2], [(2,3), f3]])
639
+ sage: f.end_points()
640
+ [0, 1, 2, 3]
641
+ sage: f = piecewise([([0,0], sin(x)), ((0,2), cos(x))]); f
642
+ piecewise(x|-->sin(x) on {0}, x|-->cos(x) on (0, 2); x)
643
+ sage: f.end_points()
644
+ [0, 2]
645
+ """
646
+ s = set()
647
+ for domain, func in parameters:
648
+ for interval in domain:
649
+ s.add(interval.lower())
650
+ s.add(interval.upper())
651
+ s.discard(minus_infinity)
652
+ s.discard(infinity)
653
+ return sorted(s)
654
+
655
+ def piecewise_add(self, parameters, variable, other):
656
+ """
657
+ Return a new piecewise function with domain the union
658
+ of the original domains and functions summed. Undefined
659
+ intervals in the union domain get function value `0`.
660
+
661
+ EXAMPLES::
662
+
663
+ sage: f = piecewise([([0,1], 1), ((2,3), x)])
664
+ sage: g = piecewise([((1/2, 2), x)])
665
+ sage: f.piecewise_add(g).unextend_zero()
666
+ piecewise(x|-->1 on (0, 1/2],
667
+ x|-->x + 1 on (1/2, 1],
668
+ x|-->x on (1, 2) ∪ (2, 3); x)
669
+ """
670
+ points = ([minus_infinity] +
671
+ sorted(set(self.end_points() + other.end_points())) +
672
+ [infinity])
673
+ domain = []
674
+ funcs = []
675
+ contains_lower = False
676
+ contains_upper = False
677
+ for i in range(len(points) - 1):
678
+ a, b = points[i], points[i + 1]
679
+ try:
680
+ contains_lower = (self.domain().contains(a) or
681
+ other.domain().contains(a)) and not contains_upper
682
+ contains_upper = (self.domain().contains(b) or
683
+ other.domain().contains(b))
684
+ if contains_lower:
685
+ if contains_upper:
686
+ rs = RealSet.closed(a, b)
687
+ else:
688
+ rs = RealSet.closed_open(a, b)
689
+ else:
690
+ if contains_upper:
691
+ rs = RealSet.open_closed(a, b)
692
+ else:
693
+ rs = RealSet.open(a, b)
694
+ point = (b + a) / 2
695
+ except ValueError:
696
+ if a == minus_infinity and b == infinity:
697
+ rs = RealSet.open(minus_infinity, infinity)
698
+ point = 0
699
+ elif a == minus_infinity:
700
+ if contains_lower:
701
+ rs = RealSet.unbounded_below_closed(b)
702
+ else:
703
+ rs = RealSet.unbounded_below_open(b)
704
+ point = b - 1
705
+ elif b == infinity:
706
+ if contains_upper:
707
+ rs = RealSet.unbounded_above_closed(a)
708
+ else:
709
+ rs = RealSet.unbounded_above_open(a)
710
+ point = a + 1
711
+ else:
712
+ raise
713
+ try:
714
+ ex1 = self.expression_at(point)
715
+ except ValueError:
716
+ ex1 = 0
717
+ try:
718
+ ex2 = other.expression_at(point)
719
+ except ValueError:
720
+ ex2 = 0
721
+ ex = ex1 + ex2
722
+ if i > 0 and funcs[-1] == ex:
723
+ # extend the previous domain
724
+ rs += domain[-1]
725
+ domain[-1] = rs
726
+ else:
727
+ domain += rs
728
+ funcs.append(ex)
729
+ return piecewise(zip(domain, funcs))
730
+
731
+ def integral(self, parameters, variable, x=None, a=None, b=None, definite=False, **kwds):
732
+ r"""
733
+ By default, return the indefinite integral of the function.
734
+
735
+ If ``definite=True`` is given, returns the definite integral.
736
+
737
+ AUTHOR:
738
+
739
+ - Paul Butler
740
+
741
+ EXAMPLES::
742
+
743
+ sage: f1(x) = 1 - x
744
+ sage: f = piecewise([((0,1), 1), ((1,2), f1)])
745
+ sage: f.integral(definite=True)
746
+ 1/2
747
+
748
+ ::
749
+
750
+ sage: f1(x) = -1
751
+ sage: f2(x) = 2
752
+ sage: f = piecewise([((0,pi/2), f1), ((pi/2,pi), f2)])
753
+ sage: f.integral(definite=True)
754
+ 1/2*pi
755
+
756
+ sage: f1(x) = 2
757
+ sage: f2(x) = 3 - x
758
+ sage: f = piecewise([[(-2, 0), f1], [(0, 3), f2]])
759
+ sage: f.integral()
760
+ piecewise(x|-->2*x + 4 on (-2, 0),
761
+ x|-->-1/2*x^2 + 3*x + 4 on (0, 3); x)
762
+
763
+ sage: f1(y) = -1
764
+ sage: f2(y) = y + 3
765
+ sage: f3(y) = -y - 1
766
+ sage: f4(y) = y^2 - 1
767
+ sage: f5(y) = 3
768
+ sage: f = piecewise([[[-4,-3], f1], [(-3,-2), f2], [[-2,0], f3],
769
+ ....: [(0,2), f4], [[2,3], f5]])
770
+ sage: F = f.integral(y); F
771
+ piecewise(y|-->-y - 4 on [-4, -3],
772
+ y|-->1/2*y^2 + 3*y + 7/2 on (-3, -2),
773
+ y|-->-1/2*y^2 - y - 1/2 on [-2, 0],
774
+ y|-->1/3*y^3 - y - 1/2 on (0, 2),
775
+ y|-->3*y - 35/6 on [2, 3]; y)
776
+
777
+ Ensure results are consistent with FTC::
778
+
779
+ sage: F(-3) - F(-4)
780
+ -1
781
+ sage: F(-1) - F(-3)
782
+ 1
783
+ sage: F(2) - F(0)
784
+ 2/3
785
+ sage: f.integral(y, 0, 2)
786
+ 2/3
787
+ sage: F(3) - F(-4)
788
+ 19/6
789
+ sage: f.integral(y, -4, 3)
790
+ 19/6
791
+ sage: f.integral(definite=True)
792
+ 19/6
793
+
794
+ ::
795
+
796
+ sage: f1(y) = (y+3)^2
797
+ sage: f2(y) = y+3
798
+ sage: f3(y) = 3
799
+ sage: f = piecewise([[(-infinity, -3), f1], [(-3, 0), f2],
800
+ ....: [(0, infinity), f3]])
801
+ sage: f.integral()
802
+ piecewise(y|-->1/3*y^3 + 3*y^2 + 9*y + 9 on (-oo, -3),
803
+ y|-->1/2*y^2 + 3*y + 9/2 on (-3, 0),
804
+ y|-->3*y + 9/2 on (0, +oo); y)
805
+
806
+ ::
807
+
808
+ sage: f1(x) = e^(-abs(x))
809
+ sage: f = piecewise([[(-infinity, infinity), f1]])
810
+ sage: result = f.integral(definite=True)
811
+ ...
812
+ sage: result
813
+ 2
814
+ sage: f.integral()
815
+ piecewise(x|-->-integrate(e^(-abs(x)), x, x, +Infinity) on (-oo, +oo); x)
816
+
817
+ ::
818
+
819
+ sage: f = piecewise([((0, 5), cos(x))])
820
+ sage: f.integral()
821
+ piecewise(x|-->sin(x) on (0, 5); x)
822
+
823
+ TESTS:
824
+
825
+ Verify that piecewise integrals of zero work (:issue:`10841`)::
826
+
827
+ sage: f0(x) = 0
828
+ sage: f = piecewise([[[0,1], f0]])
829
+ sage: f.integral(x,0,1)
830
+ 0
831
+ sage: f = piecewise([[[0,1], 0]])
832
+ sage: f.integral(x,0,1)
833
+ 0
834
+ sage: f = piecewise([[[0,1], SR(0)]])
835
+ sage: f.integral(x,0,1)
836
+ 0
837
+
838
+ Check that the algorithm keyword can be used::
839
+
840
+ sage: # needs sage.libs.giac
841
+ sage: ex = piecewise([([0, 1], 1), ((1, oo), 1/x**2)])
842
+ sage: integral(ex, x, 0, 100, algorithm='sympy')
843
+ 199/100
844
+ sage: integral(ex, x, algorithm='sympy')
845
+ piecewise(x|-->x on [0, 1], x|-->-1/x + 2 on (1, +oo); x)
846
+ """
847
+ if a is not None and b is not None:
848
+ F = self.integral(x, **kwds)
849
+ return F(b) - F(a)
850
+
851
+ if a is not None or b is not None:
852
+ raise TypeError('only one endpoint given')
853
+
854
+ area = 0
855
+ new_pieces = []
856
+
857
+ if x is None:
858
+ x = self.default_variable()
859
+
860
+ # The integral is computed by iterating over the pieces in order.
861
+ # The definite integral for each piece is calculated and accumulated in `area`.
862
+ # The indefinite integral of each piece is also calculated,
863
+ # and the `area` before each piece is added to the piece.
864
+ #
865
+ # If a definite integral is requested, `area` is returned.
866
+ # Otherwise, a piecewise function is constructed from the indefinite integrals
867
+ # and returned.
868
+ #
869
+ # An exception is made if integral is called on a piecewise function
870
+ # that starts at -infinity. In this case, we do not try to calculate the
871
+ # definite integral of the first piece, and the value of `area` remains 0
872
+ # after the first piece.
873
+
874
+ from sage.symbolic.assumptions import assume, forget
875
+ for domain, fun in parameters:
876
+ for interval in domain:
877
+ start = interval.lower()
878
+ end = interval.upper()
879
+ if start == -infinity and not definite:
880
+ fun_integrated = fun.integral(x, end, x, **kwds)
881
+ else:
882
+ try:
883
+ assume(start < x)
884
+ except ValueError: # Assumption is redundant
885
+ pass
886
+ fun_integrated = fun.integral(x, start, x, **kwds) + area
887
+ forget(start < x)
888
+ if definite or end != infinity:
889
+ area += fun.integral(x, start, end, **kwds)
890
+ new_pieces.append([interval, SR(fun_integrated).function(x)])
891
+
892
+ if definite:
893
+ return SR(area)
894
+ else:
895
+ return piecewise(new_pieces)
896
+
897
+ def critical_points(self, parameters, variable):
898
+ """
899
+ Return the critical points of this piecewise function.
900
+
901
+ EXAMPLES::
902
+
903
+ sage: R.<x> = QQ[]
904
+ sage: f1 = x^0
905
+ sage: f2 = 10*x - x^2
906
+ sage: f3 = 3*x^4 - 156*x^3 + 3036*x^2 - 26208*x
907
+ sage: f = piecewise([[(0,3), f1], [(3,10), f2], [(10,20), f3]])
908
+ sage: expected = [5, 12, 13, 14]
909
+ sage: all(abs(e-a) < 0.001 for e,a in zip(expected, f.critical_points()))
910
+ True
911
+
912
+ TESTS:
913
+
914
+ Use variables other than x (:issue:`13836`)::
915
+
916
+ sage: R.<y> = QQ[]
917
+ sage: f1 = y^0
918
+ sage: f2 = 10*y - y^2
919
+ sage: f3 = 3*y^4 - 156*y^3 + 3036*y^2 - 26208*y
920
+ sage: f = piecewise([[(0,3), f1], [(3,10), f2], [(10,20), f3]])
921
+ sage: expected = [5, 12, 13, 14]
922
+ sage: all(abs(e-a) < 0.001 for e,a in zip(expected, f.critical_points()))
923
+ True
924
+ """
925
+ from sage.calculus.calculus import maxima
926
+ x = self.default_variable()
927
+ crit_pts = []
928
+ for domain, f in parameters:
929
+ for interval in domain:
930
+ a = interval.lower()
931
+ b = interval.upper()
932
+ for root in maxima.allroots(SR(f).diff(x) == 0):
933
+ root = float(root.rhs())
934
+ if a < root < b:
935
+ crit_pts.append(root)
936
+ return crit_pts
937
+
938
+ def convolution(self, parameters, variable, other):
939
+ r"""
940
+ Return the convolution function,
941
+ `f*g(t)=\int_{-\infty}^\infty f(u)g(t-u)du`, for compactly
942
+ supported `f,g`.
943
+
944
+ EXAMPLES::
945
+
946
+ sage: x = PolynomialRing(QQ, 'x').gen()
947
+
948
+ Example 0::
949
+
950
+ sage: f = piecewise([[[0,1], 1]])
951
+ sage: g = f.convolution(f); g
952
+ piecewise(x|-->x on (0, 1],
953
+ x|-->-x + 2 on (1, 2]; x)
954
+ sage: h = f.convolution(g); h
955
+ piecewise(x|-->1/2*x^2 on (0, 1],
956
+ x|-->-x^2 + 3*x - 3/2 on (1, 2],
957
+ x|-->1/2*x^2 - 3*x + 9/2 on (2, 3]; x)
958
+
959
+ Example 1::
960
+
961
+ sage: f = piecewise([[(0,1), 1], [(1,2), 2], [(2,3), 1]])
962
+ sage: g = f.convolution(f)
963
+ sage: h = f.convolution(g); h
964
+ piecewise(x|-->1/2*x^2 on (0, 1],
965
+ x|-->2*x^2 - 3*x + 3/2 on (1, 3],
966
+ x|-->-2*x^2 + 21*x - 69/2 on (3, 4],
967
+ x|-->-5*x^2 + 45*x - 165/2 on (4, 5],
968
+ x|-->-2*x^2 + 15*x - 15/2 on (5, 6],
969
+ x|-->2*x^2 - 33*x + 273/2 on (6, 8],
970
+ x|-->1/2*x^2 - 9*x + 81/2 on (8, 9]; x)
971
+
972
+ Example 2::
973
+
974
+ sage: f = piecewise([[(-1,1), 1]])
975
+ sage: g = piecewise([[(0,3), x]])
976
+ sage: f.convolution(g)
977
+ piecewise(x|-->1/2*x^2 + x + 1/2 on (-1, 1],
978
+ x|-->2*x on (1, 2],
979
+ x|-->-1/2*x^2 + x + 4 on (2, 4]; x)
980
+ sage: g = piecewise([[(0,3), 1], [(3,4), 2]])
981
+ sage: f.convolution(g)
982
+ piecewise(x|-->x + 1 on (-1, 1],
983
+ x|-->2 on (1, 2],
984
+ x|-->x on (2, 3],
985
+ x|-->-x + 6 on (3, 4],
986
+ x|-->-2*x + 10 on (4, 5]; x)
987
+
988
+ Some unbounded but convergent cases now work::
989
+
990
+ sage: p = piecewise([[(2,oo),exp(-x)]])
991
+ sage: q = piecewise([[[2,3],x]])
992
+ sage: p.convolution(q)
993
+ piecewise(x|-->(x - 3)*e^(-2) - e^(-x + 2) on (4, 5]; x)
994
+ sage: q.convolution(p)
995
+ piecewise(x|-->(x - 3)*e^(-2) - e^(-x + 2) on (4, 5]; x)
996
+
997
+ TESTS:
998
+
999
+ Check that the bugs raised in :issue:`12123` are fixed::
1000
+
1001
+ sage: f = piecewise([[(-2, 2), 2]])
1002
+ sage: g = piecewise([[(0, 2), 3/4]])
1003
+ sage: f.convolution(g)
1004
+ piecewise(x|-->3/2*x + 3 on (-2, 0],
1005
+ x|-->3 on (0, 2],
1006
+ x|-->-3/2*x + 6 on (2, 4]; x)
1007
+ sage: f = piecewise([[(-1, 1), 1]])
1008
+ sage: g = piecewise([[(0, 1), x], [(1, 2), -x + 2]])
1009
+ sage: f.convolution(g)
1010
+ piecewise(x|-->1/2*x^2 + x + 1/2 on (-1, 0],
1011
+ x|-->-1/2*x^2 + x + 1/2 on (0, 2],
1012
+ x|-->1/2*x^2 - 3*x + 9/2 on (2, 3]; x)
1013
+ """
1014
+ from sage.symbolic.integration.integral import definite_integral
1015
+ f = self
1016
+ g = other
1017
+ if not f.end_points() or not g.end_points():
1018
+ raise ValueError('one of the piecewise functions is nowhere defined')
1019
+ fd, f0 = parameters[0]
1020
+ gd, g0 = next(other.items())
1021
+ if len(f) == 1 == len(g):
1022
+ a1 = fd[0].lower()
1023
+ a2 = fd[0].upper()
1024
+ b1 = gd[0].lower()
1025
+ b2 = gd[0].upper()
1026
+ a1b1 = a1 + b1
1027
+ a2b2 = a2 + b2
1028
+ delta_a = a2 - a1
1029
+ delta_b = b2 - b1
1030
+
1031
+ # this fails in some unbounded cases:
1032
+ a1b2 = a1 + b2
1033
+ a2b1 = a2 + b1
1034
+
1035
+ todo = []
1036
+ if delta_a > delta_b:
1037
+ if a1b2 is not minus_infinity:
1038
+ todo.append((a1b1, a1b2, a1, variable - b1))
1039
+ todo.append((a1b2, a2b1, variable - b2, variable - b1))
1040
+ if a2b1 is not infinity:
1041
+ todo.append((a2b1, a2b2, variable - b2, a2))
1042
+ elif delta_a < delta_b:
1043
+ if a2b1 is not minus_infinity:
1044
+ todo.append((a1b1, a2b1, a1, variable - b1))
1045
+ todo.append((a2b1, a1b2, a1, a2))
1046
+ if a1b2 is not infinity:
1047
+ todo.append((a1b2, a2b2, variable - b2, a2))
1048
+ else:
1049
+ if a2b1 is not minus_infinity:
1050
+ todo.append((a1b1, a2b1, a1, variable - b1))
1051
+ todo.append((a2b1, a2b2, variable - b2, a2))
1052
+
1053
+ if not todo:
1054
+ raise ValueError("no domain of integration")
1055
+
1056
+ with SR.temp_var() as uu:
1057
+ i1 = f0.subs({variable: uu})
1058
+ i2 = g0.subs({variable: variable - uu})
1059
+ expr = i1 * i2
1060
+ h = piecewise([[(start, stop),
1061
+ definite_integral(expr, uu, mini, maxi)]
1062
+ for start, stop, mini, maxi in todo])
1063
+ flat_zero = piecewise([[(minus_infinity, infinity), 0]])
1064
+ return (flat_zero.piecewise_add(h)).unextend_zero() # why ?
1065
+
1066
+ z = piecewise([[(0, 0), 0]])
1067
+ for fpiece in f.pieces():
1068
+ for gpiece in g.pieces():
1069
+ h = gpiece.convolution(fpiece)
1070
+ z = z.piecewise_add(h)
1071
+ return z.unextend_zero()
1072
+
1073
+ def trapezoid(self, parameters, variable, N):
1074
+ """
1075
+ Return the piecewise line function defined by the trapezoid rule
1076
+ for numerical integration based on a subdivision of each domain
1077
+ interval into N subintervals.
1078
+
1079
+ EXAMPLES::
1080
+
1081
+ sage: f = piecewise([[[0,1], x^2],
1082
+ ....: [RealSet.open_closed(1,2), 5 - x^2]])
1083
+ sage: f.trapezoid(2)
1084
+ piecewise(x|-->1/2*x on (0, 1/2),
1085
+ x|-->3/2*x - 1/2 on (1/2, 1),
1086
+ x|-->7/2*x - 5/2 on (1, 3/2),
1087
+ x|-->-7/2*x + 8 on (3/2, 2); x)
1088
+ sage: f = piecewise([[[-1,1], 1 - x^2]])
1089
+ sage: f.trapezoid(4).integral(definite=True)
1090
+ 5/4
1091
+ sage: f = piecewise([[[-1,1], 1/2 + x - x^3]]) ## example 3
1092
+ sage: f.trapezoid(6).integral(definite=True)
1093
+ 1
1094
+
1095
+ TESTS:
1096
+
1097
+ Use variables or rings other than x (:issue:`13836`)::
1098
+
1099
+ sage: R.<y> = QQ[]
1100
+ sage: f1 = y^2
1101
+ sage: f2 = 5 - y^2
1102
+ sage: f = piecewise([[[0,1], f1], [RealSet.open_closed(1,2), f2]])
1103
+ sage: f.trapezoid(2)
1104
+ piecewise(y|-->1/2*y on (0, 1/2),
1105
+ y|-->3/2*y - 1/2 on (1/2, 1),
1106
+ y|-->7/2*y - 5/2 on (1, 3/2),
1107
+ y|-->-7/2*y + 8 on (3/2, 2); y)
1108
+ """
1109
+ def func(x0, x1):
1110
+ f0, f1 = self(x0), self(x1)
1111
+ return [[(x0, x1), f0 + (f1-f0) * (x1-x0)**(-1)
1112
+ * (self.default_variable()-x0)]]
1113
+ rsum = []
1114
+ for domain, f in parameters:
1115
+ for interval in domain:
1116
+ a = interval.lower()
1117
+ b = interval.upper()
1118
+ h = (b-a)/N
1119
+ for i in range(N):
1120
+ x0 = a+i*h
1121
+ x1 = a+(i+1)*h
1122
+ rsum += func(x0, x1)
1123
+ return piecewise(rsum)
1124
+
1125
+ def laplace(self, parameters, variable, x='x', s='t'):
1126
+ r"""
1127
+ Return the Laplace transform of ``self`` with respect to the variable
1128
+ var.
1129
+
1130
+ INPUT:
1131
+
1132
+ - ``x`` -- variable of ``self``
1133
+
1134
+ - ``s`` -- variable of Laplace transform
1135
+
1136
+ We assume that a piecewise function is 0 outside of its domain and
1137
+ that the left-most endpoint of the domain is 0.
1138
+
1139
+ EXAMPLES::
1140
+
1141
+ sage: x, s, w = var('x, s, w')
1142
+ sage: f = piecewise([[(0,1), 1], [[1,2], 1 - x]])
1143
+ sage: f.laplace(x, s)
1144
+ -e^(-s)/s + (s + 1)*e^(-2*s)/s^2 + 1/s - e^(-s)/s^2
1145
+ sage: f.laplace(x, w)
1146
+ -e^(-w)/w + (w + 1)*e^(-2*w)/w^2 + 1/w - e^(-w)/w^2
1147
+
1148
+ ::
1149
+
1150
+ sage: y, t = var('y, t')
1151
+ sage: f = piecewise([[[1,2], 1 - y]])
1152
+ sage: f.laplace(y, t)
1153
+ (t + 1)*e^(-2*t)/t^2 - e^(-t)/t^2
1154
+
1155
+ ::
1156
+
1157
+ sage: s = var('s')
1158
+ sage: t = var('t')
1159
+ sage: f1(t) = -t
1160
+ sage: f2(t) = 2
1161
+ sage: f = piecewise([[[0,1], f1], [(1,infinity), f2]])
1162
+ sage: f.laplace(t, s)
1163
+ (s + 1)*e^(-s)/s^2 + 2*e^(-s)/s - 1/s^2
1164
+ """
1165
+ from sage.symbolic.assumptions import assume, forget
1166
+
1167
+ x = SR.var(x)
1168
+ s = SR.var(s)
1169
+ assume(s > 0)
1170
+ exp_sx = (-s * x).exp()
1171
+ result = 0
1172
+ for domain, f in parameters:
1173
+ for interval in domain:
1174
+ a = interval.lower()
1175
+ b = interval.upper()
1176
+ result += (SR(f) * exp_sx).integral(x, a, b)
1177
+ forget(s > 0)
1178
+ return result
1179
+
1180
+ def fourier_series_cosine_coefficient(self, parameters,
1181
+ variable, n, L=None):
1182
+ r"""
1183
+ Return the `n`-th cosine coefficient of the Fourier series of
1184
+ the periodic function `f` extending the piecewise-defined
1185
+ function ``self``.
1186
+
1187
+ Given an integer `n\geq 0`, the `n`-th cosine coefficient of
1188
+ the Fourier series of `f` is defined by
1189
+
1190
+ .. MATH::
1191
+
1192
+ a_n = \frac{1}{L}\int_{-L}^L
1193
+ f(x)\cos\left(\frac{n\pi x}{L}\right) dx,
1194
+
1195
+ where `L` is the half-period of `f`. For `n\geq 1`, `a_n` is
1196
+ the coefficient of `\cos(n\pi x/L)` in the Fourier series of
1197
+ `f`, while `a_0` is twice the coefficient of the constant
1198
+ term `\cos(0 x)`, i.e. twice the mean value of `f` over one
1199
+ period (cf. :meth:`fourier_series_partial_sum`).
1200
+
1201
+ INPUT:
1202
+
1203
+ - ``n`` -- nonnegative integer
1204
+
1205
+ - ``L`` -- (default: ``None``) the half-period of `f`; if none
1206
+ is provided, `L` is assumed to be the half-width of the domain
1207
+ of ``self``
1208
+
1209
+ OUTPUT: the Fourier coefficient `a_n`, as defined above
1210
+
1211
+ EXAMPLES:
1212
+
1213
+ A triangle wave function of period 2::
1214
+
1215
+ sage: f = piecewise([((0,1), x), ((1,2), 2 - x)])
1216
+ sage: f.fourier_series_cosine_coefficient(0)
1217
+ 1
1218
+ sage: f.fourier_series_cosine_coefficient(3)
1219
+ -4/9/pi^2
1220
+
1221
+ If the domain of the piecewise-defined function encompasses
1222
+ more than one period, the half-period must be passed as the
1223
+ second argument; for instance::
1224
+
1225
+ sage: f2 = piecewise([((0,1), x), ((1,2), 2 - x),
1226
+ ....: ((2,3), x - 2), ((3,4), 2 - (x-2))])
1227
+ sage: bool(f2.restriction((0,2)) == f) # f2 extends f on (0,4)
1228
+ True
1229
+ sage: f2.fourier_series_cosine_coefficient(3, 1) # half-period = 1
1230
+ -4/9/pi^2
1231
+
1232
+ The default half-period is 2 and one has::
1233
+
1234
+ sage: f2.fourier_series_cosine_coefficient(3) # half-period = 2
1235
+ 0
1236
+
1237
+ The Fourier coefficient `-4/(9\pi^2)` obtained above is actually
1238
+ recovered for `n=6`::
1239
+
1240
+ sage: f2.fourier_series_cosine_coefficient(6)
1241
+ -4/9/pi^2
1242
+
1243
+ Other examples::
1244
+
1245
+ sage: f(x) = x^2
1246
+ sage: f = piecewise([[(-1,1), f]])
1247
+ sage: f.fourier_series_cosine_coefficient(2)
1248
+ pi^(-2)
1249
+ sage: f1(x) = -1
1250
+ sage: f2(x) = 2
1251
+ sage: f = piecewise([[(-pi, pi/2), f1], [(pi/2, pi), f2]])
1252
+ sage: f.fourier_series_cosine_coefficient(5, pi)
1253
+ -3/5/pi
1254
+ """
1255
+ from sage.functions.trig import cos
1256
+ from sage.symbolic.constants import pi
1257
+ L0 = (self.domain().sup() - self.domain().inf()) / 2
1258
+ if not L:
1259
+ L = L0
1260
+ else:
1261
+ m = L0 / L
1262
+ if not (m.is_integer() and m > 0):
1263
+ raise ValueError("the width of the domain of " +
1264
+ "{} is not a multiple ".format(self) +
1265
+ "of the given period")
1266
+ result = 0
1267
+ for domain, f in parameters:
1268
+ for interval in domain:
1269
+ a = interval.lower()
1270
+ b = interval.upper()
1271
+ result += (f*cos(pi*variable*n/L)).integrate(variable, a, b)
1272
+ return SR(result / L0).simplify_trig()
1273
+
1274
+ def fourier_series_sine_coefficient(self, parameters, variable,
1275
+ n, L=None):
1276
+ r"""
1277
+ Return the `n`-th sine coefficient of the Fourier series of
1278
+ the periodic function `f` extending the piecewise-defined
1279
+ function ``self``.
1280
+
1281
+ Given an integer `n\geq 0`, the `n`-th sine coefficient of
1282
+ the Fourier series of `f` is defined by
1283
+
1284
+ .. MATH::
1285
+
1286
+ b_n = \frac{1}{L}\int_{-L}^L
1287
+ f(x)\sin\left(\frac{n\pi x}{L}\right) dx,
1288
+
1289
+ where `L` is the half-period of `f`. The number `b_n` is
1290
+ the coefficient of `\sin(n\pi x/L)` in the Fourier
1291
+ series of `f` (cf. :meth:`fourier_series_partial_sum`).
1292
+
1293
+ INPUT:
1294
+
1295
+ - ``n`` -- nonnegative integer
1296
+
1297
+ - ``L`` -- (default: ``None``) the half-period of `f`; if none
1298
+ is provided, `L` is assumed to be the half-width of the domain
1299
+ of ``self``
1300
+
1301
+ OUTPUT: the Fourier coefficient `b_n`, as defined above
1302
+
1303
+ EXAMPLES:
1304
+
1305
+ A square wave function of period 2::
1306
+
1307
+ sage: f = piecewise([((-1,0), -1), ((0,1), 1)])
1308
+ sage: f.fourier_series_sine_coefficient(1)
1309
+ 4/pi
1310
+ sage: f.fourier_series_sine_coefficient(2)
1311
+ 0
1312
+ sage: f.fourier_series_sine_coefficient(3)
1313
+ 4/3/pi
1314
+
1315
+ If the domain of the piecewise-defined function encompasses
1316
+ more than one period, the half-period must be passed as the
1317
+ second argument; for instance::
1318
+
1319
+ sage: f2 = piecewise([((-1,0), -1), ((0,1), 1),
1320
+ ....: ((1,2), -1), ((2,3), 1)])
1321
+ sage: bool(f2.restriction((-1,1)) == f) # f2 extends f on (-1,3)
1322
+ True
1323
+ sage: f2.fourier_series_sine_coefficient(1, 1) # half-period = 1
1324
+ 4/pi
1325
+ sage: f2.fourier_series_sine_coefficient(3, 1) # half-period = 1
1326
+ 4/3/pi
1327
+
1328
+ The default half-period is 2 and one has::
1329
+
1330
+ sage: f2.fourier_series_sine_coefficient(1) # half-period = 2
1331
+ 0
1332
+ sage: f2.fourier_series_sine_coefficient(3) # half-period = 2
1333
+ 0
1334
+
1335
+ The Fourier coefficients obtained from ``f`` are actually
1336
+ recovered for `n=2` and `n=6` respectively::
1337
+
1338
+ sage: f2.fourier_series_sine_coefficient(2)
1339
+ 4/pi
1340
+ sage: f2.fourier_series_sine_coefficient(6)
1341
+ 4/3/pi
1342
+ """
1343
+ from sage.functions.trig import sin
1344
+ from sage.symbolic.constants import pi
1345
+ L0 = (self.domain().sup() - self.domain().inf()) / 2
1346
+ if not L:
1347
+ L = L0
1348
+ else:
1349
+ m = L0 / L
1350
+ if not (m.is_integer() and m > 0):
1351
+ raise ValueError("the width of the domain of " +
1352
+ "{} is not a multiple ".format(self) +
1353
+ "of the given period")
1354
+ result = 0
1355
+ for domain, f in parameters:
1356
+ for interval in domain:
1357
+ a = interval.lower()
1358
+ b = interval.upper()
1359
+ result += (f*sin(pi*variable*n/L)).integrate(variable, a, b)
1360
+ return SR(result/L0).simplify_trig()
1361
+
1362
+ def fourier_series_partial_sum(self, parameters, variable, N,
1363
+ L=None):
1364
+ r"""
1365
+ Return the partial sum up to a given order of the Fourier series
1366
+ of the periodic function `f` extending the piecewise-defined
1367
+ function ``self``.
1368
+
1369
+ The Fourier partial sum of order `N` is defined as
1370
+
1371
+ .. MATH::
1372
+
1373
+ S_{N}(x) = \frac{a_0}{2} + \sum_{n=1}^{N} \left[
1374
+ a_n\cos\left(\frac{n\pi x}{L}\right)
1375
+ + b_n\sin\left(\frac{n\pi x}{L}\right)\right],
1376
+
1377
+ where `L` is the half-period of `f` and the `a_n`'s and `b_n`'s
1378
+ are respectively the cosine coefficients and sine coefficients
1379
+ of the Fourier series of `f` (cf.
1380
+ :meth:`fourier_series_cosine_coefficient` and
1381
+ :meth:`fourier_series_sine_coefficient`).
1382
+
1383
+ INPUT:
1384
+
1385
+ - ``N`` -- positive integer; the order of the partial sum
1386
+
1387
+ - ``L`` -- (default: ``None``) the half-period of `f`; if none
1388
+ is provided, `L` is assumed to be the half-width of the domain
1389
+ of ``self``
1390
+
1391
+ OUTPUT:
1392
+
1393
+ - the partial sum `S_{N}(x)`, as a symbolic expression
1394
+
1395
+ EXAMPLES:
1396
+
1397
+ A square wave function of period 2::
1398
+
1399
+ sage: f = piecewise([((-1,0), -1), ((0,1), 1)])
1400
+ sage: f.fourier_series_partial_sum(5)
1401
+ 4/5*sin(5*pi*x)/pi + 4/3*sin(3*pi*x)/pi + 4*sin(pi*x)/pi
1402
+
1403
+ If the domain of the piecewise-defined function encompasses
1404
+ more than one period, the half-period must be passed as the
1405
+ second argument; for instance::
1406
+
1407
+ sage: f2 = piecewise([((-1,0), -1), ((0,1), 1),
1408
+ ....: ((1,2), -1), ((2,3), 1)])
1409
+ sage: bool(f2.restriction((-1,1)) == f) # f2 extends f on (-1,3)
1410
+ True
1411
+ sage: f2.fourier_series_partial_sum(5, 1) # half-period = 1
1412
+ 4/5*sin(5*pi*x)/pi + 4/3*sin(3*pi*x)/pi + 4*sin(pi*x)/pi
1413
+ sage: bool(f2.fourier_series_partial_sum(5, 1) ==
1414
+ ....: f.fourier_series_partial_sum(5))
1415
+ True
1416
+
1417
+ The default half-period is 2, so that skipping the second
1418
+ argument yields a different result::
1419
+
1420
+ sage: f2.fourier_series_partial_sum(5) # half-period = 2
1421
+ 4*sin(pi*x)/pi
1422
+
1423
+ An example of partial sum involving both cosine and sine terms::
1424
+
1425
+ sage: f = piecewise([((-1,0), 0), ((0,1/2), 2*x),
1426
+ ....: ((1/2,1), 2*(1-x))])
1427
+ sage: f.fourier_series_partial_sum(5)
1428
+ -2*cos(2*pi*x)/pi^2 + 4/25*sin(5*pi*x)/pi^2
1429
+ - 4/9*sin(3*pi*x)/pi^2 + 4*sin(pi*x)/pi^2 + 1/4
1430
+ """
1431
+ from sage.symbolic.constants import pi
1432
+ from sage.functions.trig import cos, sin
1433
+ from sage.arith.srange import srange
1434
+
1435
+ if not L:
1436
+ L = (self.domain().sup() - self.domain().inf()) / 2
1437
+ x = self.default_variable()
1438
+ a0 = self.fourier_series_cosine_coefficient(0, L)
1439
+ result = a0/2 + sum([(self.fourier_series_cosine_coefficient(n, L)*cos(n*pi*x/L) +
1440
+ self.fourier_series_sine_coefficient(n, L)*sin(n*pi*x/L))
1441
+ for n in srange(1, N+1)])
1442
+ return SR(result).expand()
1443
+
1444
+ def _sympy_(self, parameters, variable):
1445
+ """
1446
+ Convert this piecewise expression to its SymPy equivalent.
1447
+
1448
+ EXAMPLES::
1449
+
1450
+ sage: ex = piecewise([((0, 1), pi), ([1, 2], x)])
1451
+ sage: f = ex._sympy_(); f # needs sympy
1452
+ Piecewise((pi, (x > 0) & (x < 1)), (x, (x >= 1) & (x <= 2)))
1453
+ sage: f.diff() # needs sympy
1454
+ Piecewise((0, (x > 0) & (x < 1)), (1, (x >= 1) & (x <= 2)))
1455
+
1456
+ sage: ex = piecewise([((-100, -2), 1/x), ((1, +oo), cos(x))])
1457
+ sage: g = ex._sympy_(); g # needs sympy
1458
+ Piecewise((1/x, (x > -100) & (x < -2)), (cos(x), x > 1))
1459
+ sage: g.diff() # needs sympy
1460
+ Piecewise((-1/x**2, (x > -100) & (x < -2)), (-sin(x), x > 1))
1461
+ """
1462
+ from sympy import Piecewise as pw
1463
+ args = [(func._sympy_(),
1464
+ domain._sympy_condition_(variable))
1465
+ for domain, func in parameters]
1466
+ return pw(*args)
1467
+
1468
+ def _giac_init_(self, parameters, variable):
1469
+ """
1470
+ Convert this piecewise expression to its Giac equivalent.
1471
+
1472
+ Backward conversion is not yet implemented.
1473
+
1474
+ EXAMPLES::
1475
+
1476
+ sage: # needs giac
1477
+ sage: ex = piecewise([((0, 1), pi), ([1, 2], x)])
1478
+ sage: f = ex._giac_(); f
1479
+ piecewise(((sageVARx>0) and (1>sageVARx)),pi,((sageVARx>=1) and (2>=sageVARx)),sageVARx)
1480
+ sage: f.diff(x)
1481
+ piecewise(((sageVARx>0) and (1>sageVARx)),0,((sageVARx>=1) and (2>=sageVARx)),1)
1482
+
1483
+ sage: # needs giac
1484
+ sage: ex = piecewise([((-100, -2), 1/x), ((1, +oo), cos(x))])
1485
+ sage: g = ex._giac_(); g
1486
+ piecewise(((sageVARx>-100) and ((-2)>sageVARx)),1/sageVARx,sageVARx>1,cos(sageVARx))
1487
+ sage: g.diff(x)
1488
+ piecewise(((sageVARx>-100) and ((-2)>sageVARx)),-1/sageVARx^2,sageVARx>1,-sin(sageVARx))
1489
+
1490
+ TESTS::
1491
+
1492
+ sage: f = piecewise([([0,1], x), ((1,2), 3*x)])
1493
+ sage: a = libgiac(f) # random because verbose # needs sage.libs.giac
1494
+ sage: a # needs sage.libs.giac
1495
+ piecewise(((sageVARx>=0) and (1>=sageVARx)),sageVARx,((sageVARx>1) and (2>sageVARx)),sageVARx*3)
1496
+ """
1497
+ from sage.misc.flatten import flatten
1498
+ args = [(domain._giac_condition_(variable),
1499
+ func._giac_init_())
1500
+ for domain, func in parameters]
1501
+ args = ",".join(flatten(args))
1502
+ return f"piecewise({args})"
1503
+
1504
+
1505
+ piecewise = PiecewiseFunction()