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
sage/sets/real_set.py ADDED
@@ -0,0 +1,2760 @@
1
+ # sage_setup: distribution = sagemath-categories
2
+ # sage.doctest: needs sage.rings.real_interval_field sage.rings.real_mpfr
3
+ """
4
+ Subsets of the Real Line
5
+
6
+ This module contains subsets of the real line that can be constructed
7
+ as the union of a finite set of open and closed intervals.
8
+
9
+ EXAMPLES::
10
+
11
+ sage: RealSet(0,1)
12
+ (0, 1)
13
+ sage: RealSet((0,1), [2,3])
14
+ (0, 1) ∪ [2, 3]
15
+ sage: RealSet((1,3), (0,2))
16
+ (0, 3)
17
+ sage: RealSet(-oo, oo)
18
+ (-oo, +oo)
19
+
20
+ Brackets must be balanced in Python, so the naive notation for
21
+ half-open intervals does not work::
22
+
23
+ sage: RealSet([0,1))
24
+ Traceback (most recent call last):
25
+ ...
26
+ SyntaxError: ...
27
+
28
+ Instead, you can use the following construction functions::
29
+
30
+ sage: RealSet.open_closed(0,1)
31
+ (0, 1]
32
+ sage: RealSet.closed_open(0,1)
33
+ [0, 1)
34
+ sage: RealSet.point(1/2)
35
+ {1/2}
36
+ sage: RealSet.unbounded_below_open(0)
37
+ (-oo, 0)
38
+ sage: RealSet.unbounded_below_closed(0)
39
+ (-oo, 0]
40
+ sage: RealSet.unbounded_above_open(1)
41
+ (1, +oo)
42
+ sage: RealSet.unbounded_above_closed(1)
43
+ [1, +oo)
44
+
45
+ The lower and upper endpoints will be sorted if necessary::
46
+
47
+ sage: RealSet.interval(1, 0, lower_closed=True, upper_closed=False)
48
+ [0, 1)
49
+
50
+ Relations containing symbols and numeric values or constants::
51
+
52
+ sage: # needs sage.symbolic
53
+ sage: RealSet(x != 0)
54
+ (-oo, 0) ∪ (0, +oo)
55
+ sage: RealSet(x == pi)
56
+ {pi}
57
+ sage: RealSet(x < 1/2)
58
+ (-oo, 1/2)
59
+ sage: RealSet(1/2 < x)
60
+ (1/2, +oo)
61
+ sage: RealSet(1.5 <= x)
62
+ [1.50000000000000, +oo)
63
+
64
+ Note that multiple arguments are combined as union::
65
+
66
+ sage: RealSet(x >= 0, x < 1) # needs sage.symbolic
67
+ (-oo, +oo)
68
+ sage: RealSet(x >= 0, x > 1) # needs sage.symbolic
69
+ [0, +oo)
70
+ sage: RealSet(x >= 0, x > -1) # needs sage.symbolic
71
+ (-1, +oo)
72
+
73
+ AUTHORS:
74
+
75
+ - Laurent Claessens (2010-12-10): Interval and ContinuousSet, posted
76
+ to sage-devel at
77
+ http://www.mail-archive.com/sage-support@googlegroups.com/msg21326.html.
78
+
79
+ - Ares Ribo (2011-10-24): Extended the previous work defining the
80
+ class RealSet.
81
+
82
+ - Jordi Saludes (2011-12-10): Documentation and file reorganization.
83
+
84
+ - Volker Braun (2013-06-22): Rewrite
85
+
86
+ - Yueqi Li, Yuan Zhou (2022-07-31): Rewrite RealSet. Adapt faster operations
87
+ by scan-line (merging) techniques from the code by Matthias Köppe et al., at
88
+ https://github.com/mkoeppe/cutgeneratingfunctionology/blob/master/cutgeneratingfunctionology/igp/intervals.py
89
+ """
90
+
91
+ # ****************************************************************************
92
+ # Copyright (C) 2013 Volker Braun <vbraun.name@gmail.com>
93
+ #
94
+ # This program is free software: you can redistribute it and/or modify
95
+ # it under the terms of the GNU General Public License as published by
96
+ # the Free Software Foundation, either version 2 of the License, or
97
+ # (at your option) any later version.
98
+ # https://www.gnu.org/licenses/
99
+ # ****************************************************************************
100
+
101
+ from sage.structure.richcmp import richcmp, richcmp_method
102
+ from sage.structure.parent import Parent
103
+ from sage.structure.unique_representation import UniqueRepresentation
104
+ from sage.categories.topological_spaces import TopologicalSpaces
105
+ from sage.categories.sets_cat import EmptySetError
106
+ from sage.sets.set import Set_base, Set_boolean_operators, Set_add_sub_operators
107
+ from sage.rings.integer_ring import ZZ
108
+ from sage.rings.real_lazy import LazyFieldElement, RLF
109
+ from sage.rings.infinity import infinity, minus_infinity
110
+ from sage.misc.superseded import deprecated_function_alias
111
+ from heapq import merge
112
+
113
+
114
+ @richcmp_method
115
+ class InternalRealInterval(UniqueRepresentation, Parent):
116
+ """
117
+ A real interval.
118
+
119
+ You are not supposed to create :class:`InternalRealInterval` objects
120
+ yourself. Always use :class:`RealSet` instead.
121
+
122
+ INPUT:
123
+
124
+ - ``lower`` -- real or minus infinity; the lower bound of the interval
125
+
126
+ - ``lower_closed`` -- boolean; whether the interval is closed at the lower
127
+ bound
128
+
129
+ - ``upper`` -- real or (plus) infinity; the upper bound of the interval
130
+
131
+ - ``upper_closed`` -- boolean; whether the interval is closed at the upper
132
+ bound
133
+
134
+ - ``check`` -- boolean; whether to check the other arguments for validity
135
+ """
136
+
137
+ def __init__(self, lower, lower_closed, upper, upper_closed, check=True):
138
+ """
139
+ Initialize ``self``.
140
+
141
+ EXAMPLES::
142
+
143
+ sage: RealSet([0, oo])
144
+ Traceback (most recent call last):
145
+ ...
146
+ ValueError: interval cannot be closed at +oo
147
+ """
148
+ self._lower = lower
149
+ self._upper = upper
150
+ self._lower_closed = lower_closed
151
+ self._upper_closed = upper_closed
152
+ if check:
153
+ if not (isinstance(lower, LazyFieldElement) or lower is minus_infinity):
154
+ raise ValueError('lower bound must be a real number or -oo')
155
+ if not (isinstance(upper, LazyFieldElement) or upper is infinity):
156
+ raise ValueError('upper bound must be a real number or +oo')
157
+ if not isinstance(lower_closed, bool):
158
+ raise ValueError('lower_closed must be boolean')
159
+ if not isinstance(upper_closed, bool):
160
+ raise ValueError('upper_closed must be boolean')
161
+ if lower > upper:
162
+ raise ValueError('lower/upper bounds are not sorted')
163
+ if (lower_closed and lower == minus_infinity):
164
+ raise ValueError('interval cannot be closed at -oo')
165
+ if (upper_closed and upper == infinity):
166
+ raise ValueError('interval cannot be closed at +oo')
167
+ # TODO: take care of the empty set case.
168
+
169
+ def is_empty(self):
170
+ """
171
+ Return whether the interval is empty.
172
+
173
+ The normalized form of :class:`RealSet` has all intervals
174
+ non-empty, so this method usually returns ``False``.
175
+
176
+ OUTPUT: boolean
177
+
178
+ EXAMPLES::
179
+
180
+ sage: I = RealSet(0, 1)[0]
181
+ sage: I.is_empty()
182
+ False
183
+ """
184
+ return (self._lower == self._upper) and not (self._lower_closed and self._upper_closed)
185
+
186
+ def is_point(self):
187
+ """
188
+ Return whether the interval consists of a single point.
189
+
190
+ OUTPUT: boolean
191
+
192
+ EXAMPLES::
193
+
194
+ sage: I = RealSet(0, 1)[0]
195
+ sage: I.is_point()
196
+ False
197
+ """
198
+ return (self._lower == self._upper) and self._lower_closed and self._upper_closed
199
+
200
+ def lower(self):
201
+ """
202
+ Return the lower bound.
203
+
204
+ OUTPUT: the lower bound as it was originally specified
205
+
206
+ EXAMPLES::
207
+
208
+ sage: I = RealSet(0, 1)[0]
209
+ sage: I.lower()
210
+ 0
211
+ sage: I.upper()
212
+ 1
213
+ """
214
+ if self._lower is minus_infinity:
215
+ return minus_infinity
216
+ else:
217
+ return self._lower._value
218
+
219
+ def upper(self):
220
+ """
221
+ Return the upper bound.
222
+
223
+ OUTPUT: the upper bound as it was originally specified
224
+
225
+ EXAMPLES::
226
+
227
+ sage: I = RealSet(0, 1)[0]
228
+ sage: I.lower()
229
+ 0
230
+ sage: I.upper()
231
+ 1
232
+ """
233
+ if self._upper is infinity:
234
+ return infinity
235
+ else:
236
+ return self._upper._value
237
+
238
+ def lower_closed(self):
239
+ """
240
+ Return whether the interval is open at the lower bound.
241
+
242
+ OUTPUT: boolean
243
+
244
+ EXAMPLES::
245
+
246
+ sage: I = RealSet.open_closed(0, 1)[0]; I
247
+ (0, 1]
248
+ sage: I.lower_closed()
249
+ False
250
+ sage: I.lower_open()
251
+ True
252
+ sage: I.upper_closed()
253
+ True
254
+ sage: I.upper_open()
255
+ False
256
+ """
257
+ return self._lower_closed
258
+
259
+ def upper_closed(self):
260
+ """
261
+ Return whether the interval is closed at the lower bound.
262
+
263
+ OUTPUT: boolean
264
+
265
+ EXAMPLES::
266
+
267
+ sage: I = RealSet.open_closed(0, 1)[0]; I
268
+ (0, 1]
269
+ sage: I.lower_closed()
270
+ False
271
+ sage: I.lower_open()
272
+ True
273
+ sage: I.upper_closed()
274
+ True
275
+ sage: I.upper_open()
276
+ False
277
+ """
278
+ return self._upper_closed
279
+
280
+ def lower_open(self):
281
+ """
282
+ Return whether the interval is closed at the upper bound.
283
+
284
+ OUTPUT: boolean
285
+
286
+ EXAMPLES::
287
+
288
+ sage: I = RealSet.open_closed(0, 1)[0]; I
289
+ (0, 1]
290
+ sage: I.lower_closed()
291
+ False
292
+ sage: I.lower_open()
293
+ True
294
+ sage: I.upper_closed()
295
+ True
296
+ sage: I.upper_open()
297
+ False
298
+ """
299
+ return not self._lower_closed
300
+
301
+ def upper_open(self):
302
+ """
303
+ Return whether the interval is closed at the upper bound.
304
+
305
+ OUTPUT: boolean
306
+
307
+ EXAMPLES::
308
+
309
+ sage: I = RealSet.open_closed(0, 1)[0]; I
310
+ (0, 1]
311
+ sage: I.lower_closed()
312
+ False
313
+ sage: I.lower_open()
314
+ True
315
+ sage: I.upper_closed()
316
+ True
317
+ sage: I.upper_open()
318
+ False
319
+ """
320
+ return not self._upper_closed
321
+
322
+ def __richcmp__(self, other, op):
323
+ """
324
+ Intervals are sorted by lower bound, then upper bound.
325
+
326
+ OUTPUT: `-1`, `0`, or `+1` depending on how the intervals compare
327
+
328
+ EXAMPLES::
329
+
330
+ sage: I1 = RealSet.open_closed(1, 3)[0]; I1
331
+ (1, 3]
332
+ sage: I2 = RealSet.open_closed(0, 5)[0]; I2
333
+ (0, 5]
334
+ sage: I1 > I2
335
+ True
336
+ sage: sorted([I1, I2])
337
+ [(0, 5], (1, 3]]
338
+
339
+ TESTS:
340
+
341
+ Check if a bug in sorting is fixed (:issue:`17714`)::
342
+
343
+ sage: RealSet((0, 1),[1, 1],(1, 2))
344
+ (0, 2)
345
+ """
346
+ x = (self._lower, not self._lower_closed, self._upper, self._upper_closed)
347
+ y = (other._lower, not other._lower_closed, other._upper, other._upper_closed)
348
+ # same as richcmp((self._scan_lower(), self._scan_upper()),
349
+ # (other._scan_lower(), other._scan_upper()), op)
350
+ return richcmp(x, y, op)
351
+
352
+ element_class = LazyFieldElement
353
+
354
+ def _repr_(self):
355
+ """
356
+ Return a string representation.
357
+
358
+ OUTPUT: string
359
+
360
+ EXAMPLES::
361
+
362
+ sage: RealSet.open_closed(0, 1)
363
+ (0, 1]
364
+ sage: RealSet.point(0)
365
+ {0}
366
+ """
367
+ if self.is_point():
368
+ return '{' + str(self.lower()) + '}'
369
+ s = '[' if self._lower_closed else '('
370
+ if self.lower() is minus_infinity:
371
+ s += '-oo'
372
+ else:
373
+ s += str(self.lower())
374
+ s += ', '
375
+ if self.upper() is infinity:
376
+ s += '+oo'
377
+ else:
378
+ s += str(self.upper())
379
+ s += ']' if self._upper_closed else ')'
380
+ return s
381
+
382
+ def _latex_(self) -> str:
383
+ """
384
+ Return a latex representation of ``self``.
385
+
386
+ EXAMPLES::
387
+
388
+ sage: RealSet.open_closed(1/2, pi)._latex_() # needs sage.symbolic
389
+ '(\\frac{1}{2}, \\pi]'
390
+ sage: (RealSet.point(sqrt(2)))._latex_() # needs sage.symbolic
391
+ '\\{\\sqrt{2}\\}'
392
+ """
393
+ from sage.misc.latex import latex
394
+ if self.is_point():
395
+ # Converting to str avoids the extra whitespace
396
+ # that LatexExpr add on concatenation. We do not need
397
+ # the whitespace because we are wrapping it in
398
+ # non-letter characters.
399
+ return r'\{' + str(latex(self.lower())) + r'\}'
400
+ s = '[' if self._lower_closed else '('
401
+ s += str(latex(self.lower()))
402
+ s += ', '
403
+ s += str(latex(self.upper()))
404
+ s += ']' if self._upper_closed else ')'
405
+ return s
406
+
407
+ def _sympy_condition_(self, variable):
408
+ """
409
+ Convert to a sympy conditional expression.
410
+
411
+ INPUT:
412
+
413
+ - ``variable`` -- a symbolic variable
414
+
415
+ EXAMPLES::
416
+
417
+ sage: RealSet(0, 4)._sympy_condition_(x) # needs sage.symbolic
418
+ (0 < x) & (x < 4)
419
+ """
420
+ x = variable
421
+ if self.is_point():
422
+ return (x == self.lower())._sympy_()
423
+ true = (x == 0)._sympy_() | True # trick to get sympy's True
424
+ if self.lower() is not minus_infinity:
425
+ if self._lower_closed:
426
+ lower_condition = (self.lower() <= x)._sympy_()
427
+ else:
428
+ lower_condition = (self.lower() < x)._sympy_()
429
+ else:
430
+ lower_condition = true
431
+ if self.upper() is not infinity:
432
+ if self._upper_closed:
433
+ upper_condition = (x <= self.upper())._sympy_()
434
+ else:
435
+ upper_condition = (x < self.upper())._sympy_()
436
+ else:
437
+ upper_condition = true
438
+ return lower_condition & upper_condition
439
+
440
+ def _sympy_(self):
441
+ r"""
442
+ Return the SymPy set corresponding to ``self``.
443
+
444
+ EXAMPLES::
445
+
446
+ sage: # needs sympy
447
+ sage: RealSet.open_closed(0, 1)[0]._sympy_()
448
+ Interval.Lopen(0, 1)
449
+ sage: RealSet.point(0)[0]._sympy_() # random - this output format is sympy >= 1.9
450
+ {0}
451
+ sage: type(_)
452
+ <class 'sympy.sets.sets.FiniteSet'>
453
+ sage: RealSet.open(0,1)[0]._sympy_()
454
+ Interval.open(0, 1)
455
+ sage: RealSet.open(-oo,1)[0]._sympy_()
456
+ Interval.open(-oo, 1)
457
+ sage: RealSet.open(0, oo)[0]._sympy_()
458
+ Interval.open(0, oo)
459
+ """
460
+ from sympy import Interval
461
+ from sage.interfaces.sympy import sympy_init
462
+ sympy_init()
463
+ return Interval(self.lower(), self.upper(),
464
+ left_open=not self._lower_closed,
465
+ right_open=not self._upper_closed)
466
+
467
+ def _giac_condition_(self, variable):
468
+ """
469
+ Convert to a Giac conditional expression.
470
+
471
+ INPUT:
472
+
473
+ - ``variable`` -- a symbolic variable
474
+
475
+ EXAMPLES::
476
+
477
+ sage: RealSet(0, 4)._giac_condition_(x) # needs sage.libs.giac
478
+ '((0 < sageVARx) and (sageVARx < 4))'
479
+ """
480
+ x = variable
481
+ if self.is_point():
482
+ return (x == self.lower())._giac_init_()
483
+ true = 'true'
484
+ if self.lower() is not minus_infinity:
485
+ if self._lower_closed:
486
+ lower_condition = (self.lower() <= x)._giac_init_()
487
+ else:
488
+ lower_condition = (self.lower() < x)._giac_init_()
489
+ else:
490
+ lower_condition = true
491
+ if self.upper() is not infinity:
492
+ if self._upper_closed:
493
+ upper_condition = (x <= self.upper())._giac_init_()
494
+ else:
495
+ upper_condition = (x < self.upper())._giac_init_()
496
+ else:
497
+ upper_condition = true
498
+ return "((" + lower_condition + ") and (" + upper_condition + "))"
499
+
500
+ def closure(self):
501
+ """
502
+ Return the closure.
503
+
504
+ OUTPUT: the closure as a new :class:`InternalRealInterval`
505
+
506
+ EXAMPLES::
507
+
508
+ sage: RealSet.open(0,1)[0].closure()
509
+ [0, 1]
510
+ sage: RealSet.open(-oo,1)[0].closure()
511
+ (-oo, 1]
512
+ sage: RealSet.open(0, oo)[0].closure()
513
+ [0, +oo)
514
+ """
515
+ # Bug example: RealSet.point(5).interior().closure() returns {5}.
516
+ # TODO: take care of the empty set case.
517
+ # maybe not necessary because this is an interval class of
518
+ # :class:`RealSet` whose intervals are all non-empty.
519
+ lower_closed = (self._lower != minus_infinity)
520
+ upper_closed = (self._upper != infinity)
521
+ return InternalRealInterval(self._lower, lower_closed, self._upper, upper_closed)
522
+
523
+ def interior(self):
524
+ """
525
+ Return the interior.
526
+
527
+ OUTPUT: the interior as a new :class:`InternalRealInterval`
528
+
529
+ EXAMPLES::
530
+
531
+ sage: RealSet.closed(0, 1)[0].interior()
532
+ (0, 1)
533
+ sage: RealSet.open_closed(-oo, 1)[0].interior()
534
+ (-oo, 1)
535
+ sage: RealSet.closed_open(0, oo)[0].interior()
536
+ (0, +oo)
537
+ """
538
+ return InternalRealInterval(self._lower, False, self._upper, False)
539
+
540
+ def boundary_points(self):
541
+ """
542
+ Generate the boundary points of ``self``.
543
+
544
+ EXAMPLES::
545
+
546
+ sage: list(RealSet.open_closed(-oo, 1)[0].boundary_points())
547
+ [1]
548
+ sage: list(RealSet.open(1, 2)[0].boundary_points())
549
+ [1, 2]
550
+ """
551
+ if self._lower != minus_infinity:
552
+ yield self._lower
553
+ if self._upper != infinity:
554
+ yield self._upper
555
+
556
+ def is_connected(self, other):
557
+ """
558
+ Test whether two intervals are connected.
559
+
560
+ OUTPUT:
561
+
562
+ boolean; whether the set-theoretic union of the two intervals
563
+ has a single connected component.
564
+
565
+ EXAMPLES::
566
+
567
+ sage: I1 = RealSet.open(0, 1)[0]; I1
568
+ (0, 1)
569
+ sage: I2 = RealSet.closed(1, 2)[0]; I2
570
+ [1, 2]
571
+ sage: I1.is_connected(I2)
572
+ True
573
+ sage: I1.is_connected(I2.interior())
574
+ False
575
+ sage: I1.closure().is_connected(I2.interior())
576
+ True
577
+ sage: I2.is_connected(I1)
578
+ True
579
+ sage: I2.interior().is_connected(I1)
580
+ False
581
+ sage: I2.closure().is_connected(I1.interior())
582
+ True
583
+ sage: I3 = RealSet.closed(1/2, 3/2)[0]; I3
584
+ [1/2, 3/2]
585
+ sage: I1.is_connected(I3)
586
+ True
587
+ sage: I3.is_connected(I1)
588
+ True
589
+ """
590
+ # self is separated and below other
591
+ if self._upper < other._lower:
592
+ return False
593
+ # self is adjacent and below other
594
+ if self._upper == other._lower:
595
+ return self._upper_closed or other._lower_closed
596
+ # self is separated and above other
597
+ if other._upper < self._lower:
598
+ return False
599
+ # self is adjacent and above other
600
+ if other._upper == self._lower:
601
+ return self._lower_closed or other._upper_closed
602
+ # They are not separated
603
+ return True
604
+
605
+ def convex_hull(self, other):
606
+ """
607
+ Return the convex hull of the two intervals.
608
+
609
+ OUTPUT: the convex hull as a new :class:`InternalRealInterval`
610
+
611
+ EXAMPLES::
612
+
613
+ sage: I1 = RealSet.open(0, 1)[0]; I1
614
+ (0, 1)
615
+ sage: I2 = RealSet.closed(1, 2)[0]; I2
616
+ [1, 2]
617
+ sage: I1.convex_hull(I2)
618
+ (0, 2]
619
+ sage: I2.convex_hull(I1)
620
+ (0, 2]
621
+ sage: I1.convex_hull(I2.interior())
622
+ (0, 2)
623
+ sage: I1.closure().convex_hull(I2.interior())
624
+ [0, 2)
625
+ sage: I1.closure().convex_hull(I2)
626
+ [0, 2]
627
+ sage: I3 = RealSet.closed(1/2, 3/2)[0]; I3
628
+ [1/2, 3/2]
629
+ sage: I1.convex_hull(I3)
630
+ (0, 3/2]
631
+ """
632
+ if self._lower < other._lower:
633
+ lower = self._lower
634
+ lower_closed = self._lower_closed
635
+ elif self._lower > other._lower:
636
+ lower = other._lower
637
+ lower_closed = other._lower_closed
638
+ else:
639
+ lower = self._lower
640
+ lower_closed = self._lower_closed or other._lower_closed
641
+ if self._upper > other._upper:
642
+ upper = self._upper
643
+ upper_closed = self._upper_closed
644
+ elif self._upper < other._upper:
645
+ upper = other._upper
646
+ upper_closed = other._upper_closed
647
+ else:
648
+ upper = self._upper
649
+ upper_closed = self._upper_closed or other._upper_closed
650
+ return InternalRealInterval(lower, lower_closed, upper, upper_closed)
651
+
652
+ def intersection(self, other):
653
+ """
654
+ Return the intersection of the two intervals.
655
+
656
+ INPUT:
657
+
658
+ - ``other`` -- a :class:`InternalRealInterval`
659
+
660
+ OUTPUT: the intersection as a new :class:`InternalRealInterval`
661
+
662
+ EXAMPLES::
663
+
664
+ sage: I1 = RealSet.open(0, 2)[0]; I1
665
+ (0, 2)
666
+ sage: I2 = RealSet.closed(1, 3)[0]; I2
667
+ [1, 3]
668
+ sage: I1.intersection(I2)
669
+ [1, 2)
670
+ sage: I2.intersection(I1)
671
+ [1, 2)
672
+ sage: I1.closure().intersection(I2.interior())
673
+ (1, 2]
674
+ sage: I2.interior().intersection(I1.closure())
675
+ (1, 2]
676
+
677
+ sage: I3 = RealSet.closed(10, 11)[0]; I3
678
+ [10, 11]
679
+ sage: I1.intersection(I3)
680
+ (0, 0)
681
+ sage: I3.intersection(I1)
682
+ (0, 0)
683
+ """
684
+ lower = upper = None
685
+ lower_closed = upper_closed = None
686
+ if self._lower < other._lower:
687
+ lower = other._lower
688
+ lower_closed = other._lower_closed
689
+ elif self._lower > other._lower:
690
+ lower = self._lower
691
+ lower_closed = self._lower_closed
692
+ else:
693
+ lower = self._lower
694
+ lower_closed = self._lower_closed and other._lower_closed
695
+ if self._upper > other._upper:
696
+ upper = other._upper
697
+ upper_closed = other._upper_closed
698
+ elif self._upper < other._upper:
699
+ upper = self._upper
700
+ upper_closed = self._upper_closed
701
+ else:
702
+ upper = self._upper
703
+ upper_closed = self._upper_closed and other._upper_closed
704
+ if lower > upper:
705
+ lower = upper = RLF(0)
706
+ lower_closed = upper_closed = False
707
+ return InternalRealInterval(lower, lower_closed, upper, upper_closed)
708
+
709
+ def contains(self, x):
710
+ """
711
+ Return whether `x` is contained in the interval.
712
+
713
+ INPUT:
714
+
715
+ - ``x`` -- a real number
716
+
717
+ OUTPUT: boolean
718
+
719
+ EXAMPLES::
720
+
721
+ sage: i = RealSet.open_closed(0,2)[0]; i
722
+ (0, 2]
723
+ sage: i.contains(0)
724
+ False
725
+ sage: i.contains(1)
726
+ True
727
+ sage: i.contains(2)
728
+ True
729
+ """
730
+ if self._lower < x < self._upper:
731
+ return True
732
+ if self._lower == x:
733
+ return self._lower_closed
734
+ if self._upper == x:
735
+ return self._upper_closed
736
+ return False
737
+
738
+ def __mul__(self, right):
739
+ r"""
740
+ Scale an interval by a scalar on the left or right.
741
+
742
+ If scaled with a negative number, the interval is flipped.
743
+
744
+ EXAMPLES::
745
+
746
+ sage: i = RealSet.open_closed(0,2)[0]; i
747
+ (0, 2]
748
+ sage: 2 * i
749
+ (0, 4]
750
+ sage: 0 * i
751
+ {0}
752
+ sage: (-2) * i
753
+ [-4, 0)
754
+ sage: i * (-3)
755
+ [-6, 0)
756
+ sage: i * 0
757
+ {0}
758
+ sage: i * 1
759
+ (0, 2]
760
+
761
+ TESTS::
762
+
763
+ sage: from sage.sets.real_set import InternalRealInterval
764
+ sage: i = InternalRealInterval(RLF(0), False, RLF(0), False)
765
+ sage: (0 * i).is_empty()
766
+ True
767
+ """
768
+ if not isinstance(right, InternalRealInterval):
769
+ right = RLF(right)
770
+ if self.is_empty():
771
+ return self
772
+ lower = self._lower * right
773
+ lower_closed = self._lower_closed
774
+ upper = self._upper * right
775
+ upper_closed = self._upper_closed
776
+ scalar = right
777
+ elif not isinstance(self, InternalRealInterval):
778
+ self = RLF(self)
779
+ if right.is_empty():
780
+ return right
781
+ lower = self * right._lower
782
+ lower_closed = right._lower_closed
783
+ upper = self * right._upper
784
+ upper_closed = right._upper_closed
785
+ scalar = self
786
+ else:
787
+ return NotImplemented
788
+ if scalar == RLF(0):
789
+ return InternalRealInterval(RLF(0), True, RLF(0), True)
790
+ elif scalar < RLF(0):
791
+ lower, lower_closed, upper, upper_closed = upper, upper_closed, lower, lower_closed
792
+ if lower == -infinity:
793
+ lower = -infinity
794
+ if upper == infinity:
795
+ upper = infinity
796
+ return InternalRealInterval(lower, lower_closed,
797
+ upper, upper_closed)
798
+
799
+ def __rmul__(self, other):
800
+ r"""
801
+ Scale an interval by a scalar on the left.
802
+
803
+ If scaled with a negative number, the interval is flipped.
804
+
805
+ EXAMPLES::
806
+
807
+ sage: i = RealSet.open_closed(0,2)[0]; i
808
+ (0, 2]
809
+ sage: 2 * i
810
+ (0, 4]
811
+ sage: 0 * i
812
+ {0}
813
+ sage: (-2) * i
814
+ [-4, 0)
815
+ """
816
+ return self * other
817
+
818
+ def _scan_lower(self):
819
+ r"""
820
+ Helper function for the scan-line method of :class:`RealSet`.
821
+
822
+ OUTPUT:
823
+
824
+ An event of the form ``(x, epsilon), delta``:
825
+
826
+ - ``x`` is the lower endpoint
827
+ - ``epsilon`` is 0 if the interval is lower closed and 1 otherwise,
828
+ - ``delta = -1``
829
+
830
+ EXAMPLES::
831
+
832
+ sage: I1 = RealSet.open_closed(0,2)[0]; I1
833
+ (0, 2]
834
+ sage: I1._scan_lower()
835
+ ((0, 1), -1)
836
+ sage: I2 = RealSet([0,2])[0]; I2
837
+ [0, 2]
838
+ sage: I2._scan_lower()
839
+ ((0, 0), -1)
840
+ sage: I3 = RealSet([1,1])[0]; I3
841
+ {1}
842
+ sage: I3._scan_lower()
843
+ ((1, 0), -1)
844
+ sage: I4 = RealSet((-oo,1))[0]; I4
845
+ (-oo, 1)
846
+ sage: I4._scan_lower()
847
+ ((-Infinity, 1), -1)
848
+ """
849
+ if self._lower_closed:
850
+ return (self._lower, 0), -1
851
+ else:
852
+ return (self._lower, 1), -1
853
+
854
+ def _scan_upper(self):
855
+ r"""
856
+ Helper function for the scan-line method of :class:`RealSet`.
857
+
858
+ OUTPUT:
859
+
860
+ An event of the form ``(x, epsilon), delta``:
861
+
862
+ - ``x`` is the upper endpoint
863
+ - ``epsilon`` is 1 if the interval is upper closed and 0 otherwise,
864
+ - ``delta = +1``
865
+
866
+ EXAMPLES::
867
+
868
+ sage: I1 = RealSet.closed_open(0,2)[0]; I1
869
+ [0, 2)
870
+ sage: I1._scan_upper()
871
+ ((2, 0), 1)
872
+ sage: I2 = RealSet([0,2])[0]; I2
873
+ [0, 2]
874
+ sage: I2._scan_upper()
875
+ ((2, 1), 1)
876
+ sage: I3 = RealSet([1,1])[0]; I3
877
+ {1}
878
+ sage: I3._scan_upper()
879
+ ((1, 1), 1)
880
+ sage: I4 = RealSet((0,oo))[0]; I4
881
+ (0, +oo)
882
+ sage: I4._scan_upper()
883
+ ((+Infinity, 0), 1)
884
+ """
885
+ if self._upper_closed:
886
+ return (self._upper, 1), +1
887
+ else:
888
+ return (self._upper, 0), +1
889
+
890
+
891
+ @richcmp_method
892
+ class RealSet(UniqueRepresentation, Parent, Set_base,
893
+ Set_boolean_operators, Set_add_sub_operators):
894
+ r"""
895
+ A subset of the real line, a finite union of intervals.
896
+
897
+ INPUT:
898
+
899
+ - ``*args`` -- arguments defining a real set. Possibilities are either:
900
+
901
+ - two extended real numbers ``a, b``, to construct the open interval `(a, b)`, or
902
+ - a list/tuple/iterable of (not necessarily disjoint) intervals or real sets,
903
+ whose union is taken. The individual intervals can be specified by either
904
+
905
+ - a tuple ``(a, b)`` of two extended real numbers (constructing an open interval),
906
+ - a list ``[a, b]`` of two real numbers (constructing a closed interval),
907
+ - an :class:`InternalRealInterval`,
908
+ - an :class:`~sage.manifolds.differentiable.examples.real_line.OpenInterval`.
909
+
910
+ - ``structure`` -- (default: ``None``) if ``None``, construct the real set as an
911
+ instance of :class:`RealSet`; if ``'differentiable'``, construct it as a subset of
912
+ an instance of :class:`~sage.manifolds.differentiable.examples.real_line.RealLine`,
913
+ representing the differentiable manifold `\RR`.
914
+ - ``ambient`` -- (default: ``None``) an instance of
915
+ :class:`~sage.manifolds.differentiable.examples.real_line.RealLine`; construct
916
+ a subset of it. Using this keyword implies ``structure='differentiable'``.
917
+ - ``names`` or ``coordinate`` -- coordinate symbol for the canonical chart; see
918
+ :class:`~sage.manifolds.differentiable.examples.real_line.RealLine`. Using these
919
+ keywords implies ``structure='differentiable'``.
920
+ - ``name``, ``latex_name``, ``start_index`` -- see
921
+ :class:`~sage.manifolds.differentiable.examples.real_line.RealLine`
922
+ - ``normalized`` -- (default: ``None``) if ``True``, the input is already normalized,
923
+ i.e., ``*args`` are the connected components (type :class:`InternalRealInterval`)
924
+ of the real set in ascending order; no other keyword is provided.
925
+
926
+ There are also specialized constructors for various types of intervals:
927
+
928
+ ====================================== ====================
929
+ Constructor Interval
930
+ ====================================== ====================
931
+ :meth:`RealSet.open` `(a, b)`
932
+ :meth:`RealSet.closed` `[a, b]`
933
+ :meth:`RealSet.point` `\{a\}`
934
+ :meth:`RealSet.open_closed` `(a, b]`
935
+ :meth:`RealSet.closed_open` `[a, b)`
936
+ :meth:`RealSet.unbounded_below_closed` `(-\infty, b]`
937
+ :meth:`RealSet.unbounded_below_open` `(-\infty, b)`
938
+ :meth:`RealSet.unbounded_above_closed` `[a, +\infty)`
939
+ :meth:`RealSet.unbounded_above_open` `(a, +\infty)`
940
+ :meth:`RealSet.real_line` `(-\infty, +\infty)`
941
+ :meth:`RealSet.interval` any
942
+ ====================================== ====================
943
+
944
+ EXAMPLES::
945
+
946
+ sage: RealSet(0, 1) # open set from two numbers
947
+ (0, 1)
948
+ sage: RealSet(1, 0) # the two numbers will be sorted
949
+ (0, 1)
950
+ sage: s1 = RealSet((1,2)); s1 # tuple of two numbers = open set
951
+ (1, 2)
952
+ sage: s2 = RealSet([3,4]); s2 # list of two numbers = closed set
953
+ [3, 4]
954
+ sage: i1, i2 = s1[0], s2[0]
955
+ sage: RealSet(i2, i1) # union of intervals
956
+ (1, 2) ∪ [3, 4]
957
+ sage: RealSet((-oo, 0), x > 6, i1, RealSet.point(5), # needs sage.symbolic
958
+ ....: RealSet.closed_open(4, 3))
959
+ (-oo, 0) ∪ (1, 2) ∪ [3, 4) ∪ {5} ∪ (6, +oo)
960
+
961
+ Initialization from manifold objects::
962
+
963
+ sage: # needs sage.symbolic
964
+ sage: R = manifolds.RealLine(); R
965
+ Real number line ℝ
966
+ sage: RealSet(R)
967
+ (-oo, +oo)
968
+ sage: I02 = manifolds.OpenInterval(0, 2); I
969
+ I
970
+ sage: RealSet(I02)
971
+ (0, 2)
972
+ sage: I01_of_R = manifolds.OpenInterval(0, 1, ambient_interval=R); I01_of_R
973
+ Real interval (0, 1)
974
+ sage: RealSet(I01_of_R)
975
+ (0, 1)
976
+ sage: RealSet(I01_of_R.closure())
977
+ [0, 1]
978
+ sage: I01_of_I02 = manifolds.OpenInterval(0, 1,
979
+ ....: ambient_interval=I02); I01_of_I02
980
+ Real interval (0, 1)
981
+ sage: RealSet(I01_of_I02)
982
+ (0, 1)
983
+ sage: RealSet(I01_of_I02.closure())
984
+ (0, 1]
985
+
986
+ Real sets belong to a subcategory of topological spaces::
987
+
988
+ sage: RealSet().category()
989
+ Join of
990
+ Category of finite sets and
991
+ Category of subobjects of sets and
992
+ Category of connected topological spaces
993
+ sage: RealSet.point(1).category()
994
+ Join of
995
+ Category of finite sets and
996
+ Category of subobjects of sets and
997
+ Category of connected topological spaces
998
+ sage: RealSet([1, 2]).category()
999
+ Join of
1000
+ Category of infinite sets and
1001
+ Category of compact topological spaces and
1002
+ Category of subobjects of sets and
1003
+ Category of connected topological spaces
1004
+ sage: RealSet((1, 2), (3, 4)).category()
1005
+ Join of
1006
+ Category of infinite sets and
1007
+ Category of subobjects of sets and
1008
+ Category of topological spaces
1009
+
1010
+ Constructing real sets as manifolds or manifold subsets by passing
1011
+ ``structure='differentiable'``::
1012
+
1013
+ sage: # needs sage.symbolic
1014
+ sage: RealSet(-oo, oo, structure='differentiable')
1015
+ Real number line ℝ
1016
+ sage: RealSet([0, 1], structure='differentiable')
1017
+ Subset [0, 1] of the Real number line ℝ
1018
+ sage: _.category()
1019
+ Category of subobjects of sets
1020
+ sage: RealSet.open_closed(0, 5, structure='differentiable')
1021
+ Subset (0, 5] of the Real number line ℝ
1022
+
1023
+ This is implied when a coordinate name is given using the keywords ``coordinate``
1024
+ or ``names``::
1025
+
1026
+ sage: RealSet(0, 1, coordinate='λ') # needs sage.symbolic
1027
+ Open subset (0, 1) of the Real number line ℝ
1028
+ sage: _.category() # needs sage.symbolic
1029
+ Join of
1030
+ Category of smooth manifolds over Real Field with 53 bits of precision and
1031
+ Category of connected manifolds over Real Field with 53 bits of precision and
1032
+ Category of subobjects of sets
1033
+
1034
+ It is also implied by assigning a coordinate name using generator notation::
1035
+
1036
+ sage: R_xi.<ξ> = RealSet.real_line(); R_xi # needs sage.symbolic
1037
+ Real number line ℝ
1038
+ sage: R_xi.canonical_chart() # needs sage.symbolic
1039
+ Chart (ℝ, (ξ,))
1040
+
1041
+ With the keyword ``ambient``, we can construct a subset of a previously
1042
+ constructed manifold::
1043
+
1044
+ sage: # needs sage.symbolic
1045
+ sage: P_xi = RealSet(0, oo, ambient=R_xi); P_xi
1046
+ Open subset (0, +oo) of the Real number line ℝ
1047
+ sage: P_xi.default_chart()
1048
+ Chart ((0, +oo), (ξ,))
1049
+ sage: B_xi = RealSet(0, 1, ambient=P_xi); B_xi
1050
+ Open subset (0, 1) of the Real number line ℝ
1051
+ sage: B_xi.default_chart()
1052
+ Chart ((0, 1), (ξ,))
1053
+ sage: R_xi.subset_family()
1054
+ Set {(0, +oo), (0, 1), ℝ} of open subsets of the Real number line ℝ
1055
+ sage: F = RealSet.point(0).union(RealSet.point(1)).union(RealSet.point(2)); F
1056
+ {0} ∪ {1} ∪ {2}
1057
+ sage: F_tau = RealSet(F, names='τ'); F_tau
1058
+ Subset {0} ∪ {1} ∪ {2} of the Real number line ℝ
1059
+ sage: F_tau.manifold().canonical_chart()
1060
+ Chart (ℝ, (τ,))
1061
+
1062
+ TESTS::
1063
+
1064
+ sage: # needs sage.symbolic
1065
+ sage: TestSuite(R_xi).run()
1066
+ sage: TestSuite(P_xi).run()
1067
+ sage: R_xi.point((1,)) in P_xi
1068
+ True
1069
+ sage: R_xi.point((-1,)) in P_xi
1070
+ False
1071
+ sage: TestSuite(B_xi).run()
1072
+ sage: p = B_xi.an_element(); p
1073
+ Point on the Real number line ℝ
1074
+ sage: p.coordinates()
1075
+ (1/2,)
1076
+ """
1077
+
1078
+ @staticmethod
1079
+ def __classcall__(cls, *args, **kwds):
1080
+ """
1081
+ Normalize the input.
1082
+
1083
+ INPUT:
1084
+
1085
+ See :class:`RealSet`.
1086
+
1087
+ OUTPUT: a :class:`RealSet`
1088
+
1089
+ EXAMPLES::
1090
+
1091
+ sage: R = RealSet(RealSet.open_closed(0,1), RealSet.closed_open(2,3)); R
1092
+ (0, 1] ∪ [2, 3)
1093
+
1094
+ TESTS::
1095
+
1096
+ sage: # needs sage.symbolic
1097
+ sage: RealSet(x != 0)
1098
+ (-oo, 0) ∪ (0, +oo)
1099
+ sage: RealSet(x == pi)
1100
+ {pi}
1101
+ sage: RealSet(x < 1/2)
1102
+ (-oo, 1/2)
1103
+ sage: RealSet(1/2 < x)
1104
+ (1/2, +oo)
1105
+ sage: RealSet(1.5 <= x)
1106
+ [1.50000000000000, +oo)
1107
+ sage: RealSet(x >= -1)
1108
+ [-1, +oo)
1109
+ sage: RealSet(x > oo)
1110
+ {}
1111
+ sage: RealSet(x >= oo)
1112
+ {}
1113
+ sage: RealSet(x <= -oo)
1114
+ {}
1115
+ sage: RealSet(x < oo)
1116
+ (-oo, +oo)
1117
+ sage: RealSet(x > -oo)
1118
+ (-oo, +oo)
1119
+ sage: RealSet(x != oo)
1120
+ (-oo, +oo)
1121
+ sage: RealSet(x <= oo)
1122
+ Traceback (most recent call last):
1123
+ ...
1124
+ ValueError: interval cannot be closed at +oo
1125
+ sage: RealSet(x == oo)
1126
+ Traceback (most recent call last):
1127
+ ...
1128
+ ValueError: interval cannot be closed at +oo
1129
+ sage: RealSet(x >= -oo)
1130
+ Traceback (most recent call last):
1131
+ ...
1132
+ ValueError: interval cannot be closed at -oo
1133
+ sage: r = RealSet(2,10)
1134
+ sage: RealSet((2, 6), (4, 10)) is r
1135
+ True
1136
+ sage: RealSet(x > 2).intersection(RealSet(x < 10)) is RealSet(r[0], normalized=True)
1137
+ True
1138
+ sage: RealSet(x > 0, normalized=True)
1139
+ Traceback (most recent call last):
1140
+ ...
1141
+ AttributeError: ...
1142
+ """
1143
+ normalized = kwds.pop('normalized', False)
1144
+ if normalized:
1145
+ # Fast path: The input is already normalized: Args is a list of
1146
+ # sorted and disjoint intervals of type InternalRealInterval.
1147
+ # No other kwds should be provided.
1148
+ return UniqueRepresentation.__classcall__(cls, *args, normalized=True)
1149
+ manifold_keywords = ('structure', 'ambient', 'names', 'coordinate')
1150
+ if any(kwds.get(kwd, None)
1151
+ for kwd in manifold_keywords):
1152
+ # Got manifold keywords
1153
+ real_set = cls.__classcall__(cls, *args)
1154
+ ambient = kwds.pop('ambient', None)
1155
+ structure = kwds.pop('structure', 'differentiable')
1156
+ if structure != 'differentiable':
1157
+ # TODO
1158
+ raise NotImplementedError
1159
+
1160
+ from sage.manifolds.differentiable.examples.real_line import RealLine
1161
+ if real_set.is_universe():
1162
+ if ambient is None:
1163
+ ambient = RealLine(**kwds)
1164
+ else:
1165
+ # TODO: Check that ambient makes sense
1166
+ pass
1167
+ return ambient
1168
+
1169
+ name = kwds.pop('name', None)
1170
+ latex_name = kwds.pop('latex_name', None)
1171
+
1172
+ if ambient is None:
1173
+ ambient = RealLine(**kwds)
1174
+ else:
1175
+ # TODO: Check that ambient makes sense
1176
+ pass
1177
+
1178
+ if name is None:
1179
+ name = str(real_set)
1180
+ if latex_name is None:
1181
+ from sage.misc.latex import latex
1182
+ latex_name = latex(real_set)
1183
+
1184
+ return ambient.manifold().canonical_chart().pullback(real_set, name=name, latex_name=latex_name)
1185
+
1186
+ if kwds:
1187
+ raise TypeError(f'RealSet constructors cannot take the keyword arguments {kwds}')
1188
+
1189
+ from sage.structure.element import Expression
1190
+ if len(args) == 1 and isinstance(args[0], RealSet):
1191
+ return args[0] # common optimization
1192
+ intervals = []
1193
+ if len(args) == 2:
1194
+ # allow RealSet(0,1) interval constructor
1195
+ try:
1196
+ lower, upper = args
1197
+ lower.n()
1198
+ upper.n()
1199
+ args = (RealSet._prep(lower, upper),)
1200
+ except (AttributeError, ValueError, TypeError):
1201
+ pass
1202
+ for arg in args:
1203
+ if isinstance(arg, tuple):
1204
+ lower, upper = RealSet._prep(*arg)
1205
+ intervals.append(InternalRealInterval(lower, False, upper, False))
1206
+ elif isinstance(arg, list):
1207
+ lower, upper = RealSet._prep(*arg)
1208
+ intervals.append(InternalRealInterval(lower, True, upper, True))
1209
+ elif isinstance(arg, InternalRealInterval):
1210
+ intervals.append(arg)
1211
+ elif isinstance(arg, RealSet):
1212
+ intervals.extend(arg._intervals)
1213
+ elif isinstance(arg, Expression) and arg.is_relational():
1214
+ from operator import eq, ne, lt, gt, le, ge
1215
+
1216
+ def rel_to_interval(op, val):
1217
+ """
1218
+ Internal helper function.
1219
+ """
1220
+ oo = infinity
1221
+ try:
1222
+ val = val.pyobject()
1223
+ except AttributeError:
1224
+ pass
1225
+ val = RLF(val)
1226
+ if op == eq:
1227
+ s = [InternalRealInterval(val, True, val, True)]
1228
+ elif op == gt:
1229
+ s = [InternalRealInterval(val, False, oo, False)]
1230
+ elif op == ge:
1231
+ s = [InternalRealInterval(val, True, oo, False)]
1232
+ elif op == lt:
1233
+ s = [InternalRealInterval(-oo, False, val, False)]
1234
+ elif op == le:
1235
+ s = [InternalRealInterval(-oo, False, val, True)]
1236
+ elif op == ne:
1237
+ s = [InternalRealInterval(-oo, False, val, False),
1238
+ InternalRealInterval(val, False, oo, False)]
1239
+ else:
1240
+ raise ValueError(str(arg) + ' does not determine real interval')
1241
+ return [i for i in s if not i.is_empty()]
1242
+
1243
+ if (arg.lhs().is_symbol()
1244
+ and (arg.rhs().is_numeric() or arg.rhs().is_constant())
1245
+ and arg.rhs().is_real()):
1246
+ intervals.extend(rel_to_interval(arg.operator(), arg.rhs()))
1247
+ elif (arg.rhs().is_symbol()
1248
+ and (arg.lhs().is_numeric() or arg.lhs().is_constant())
1249
+ and arg.lhs().is_real()):
1250
+ op = arg.operator()
1251
+ if op == lt:
1252
+ op = gt
1253
+ elif op == gt:
1254
+ op = lt
1255
+ elif op == le:
1256
+ op = ge
1257
+ elif op == ge:
1258
+ op = le
1259
+ intervals.extend(rel_to_interval(op, arg.lhs()))
1260
+ else:
1261
+ raise ValueError(str(arg) + ' does not determine real interval')
1262
+ else:
1263
+ from sage.manifolds.differentiable.examples.real_line import OpenInterval
1264
+ from sage.manifolds.subsets.closure import ManifoldSubsetClosure
1265
+ if isinstance(arg, OpenInterval):
1266
+ lower, upper = RealSet._prep(arg.lower_bound(), arg.upper_bound())
1267
+ intervals.append(InternalRealInterval(lower, False, upper, False))
1268
+ elif (isinstance(arg, ManifoldSubsetClosure)
1269
+ and isinstance(arg._subset, OpenInterval)):
1270
+ interval = arg._subset
1271
+ lower, upper = RealSet._prep(interval.lower_bound(),
1272
+ interval.upper_bound())
1273
+ ambient = interval.manifold()
1274
+ ambient_lower, ambient_upper = RealSet._prep(ambient.lower_bound(),
1275
+ ambient.upper_bound())
1276
+ lower_closed = ambient_lower < lower
1277
+ upper_closed = upper < ambient_upper
1278
+ intervals.append(InternalRealInterval(lower, lower_closed,
1279
+ upper, upper_closed))
1280
+ else:
1281
+ raise ValueError(str(arg) + ' does not determine real interval')
1282
+
1283
+ union_intervals = RealSet.normalize(intervals)
1284
+ return UniqueRepresentation.__classcall__(cls, *union_intervals, normalized=True)
1285
+
1286
+ def __init__(self, *intervals, normalized=True):
1287
+ r"""
1288
+ TESTS::
1289
+
1290
+ sage: Empty = RealSet(); Empty
1291
+ {}
1292
+ sage: TestSuite(Empty).run()
1293
+ sage: I1 = RealSet.open_closed(1, 3); I1
1294
+ (1, 3]
1295
+ sage: TestSuite(I1).run()
1296
+ sage: R = RealSet(RealSet.open_closed(0,1), RealSet.closed_open(2,3)); R
1297
+ (0, 1] ∪ [2, 3)
1298
+ sage: TestSuite(R).run()
1299
+ """
1300
+ category = TopologicalSpaces()
1301
+ if len(intervals) <= 1:
1302
+ category = category.Connected()
1303
+ if all(i.is_point() for i in intervals):
1304
+ category = category.Subobjects().Finite()
1305
+ else:
1306
+ # Have at least one non-degenerate interval
1307
+ category = category.Infinite()
1308
+ inf = intervals[0].lower()
1309
+ sup = intervals[-1].upper()
1310
+ if not (len(intervals) == 1 and inf is minus_infinity and sup is infinity):
1311
+ category = category.Subobjects() # subobject of real line
1312
+ if inf is not minus_infinity and sup is not infinity:
1313
+ # Bounded
1314
+ if all(i.lower_closed() and i.upper_closed()
1315
+ for i in intervals):
1316
+ category = category.Compact()
1317
+ Parent.__init__(self, category=category)
1318
+ self._intervals = intervals
1319
+
1320
+ def __richcmp__(self, other, op):
1321
+ r"""
1322
+ Intervals are sorted by lower bound, then upper bound.
1323
+
1324
+ OUTPUT: `-1`, `0`, or `+1` depending on how the intervals compare
1325
+
1326
+ EXAMPLES::
1327
+
1328
+ sage: I1 = RealSet.open_closed(1, 3); I1
1329
+ (1, 3]
1330
+ sage: I2 = RealSet.open_closed(0, 5); I2
1331
+ (0, 5]
1332
+ sage: I1 > I2
1333
+ True
1334
+ sage: sorted([I1, I2])
1335
+ [(0, 5], (1, 3]]
1336
+ sage: I1 == I1
1337
+ True
1338
+ """
1339
+ if not isinstance(other, RealSet):
1340
+ return NotImplemented
1341
+ # note that the interval representation is normalized into a
1342
+ # unique form
1343
+ return richcmp(self._intervals, other._intervals, op)
1344
+
1345
+ def __iter__(self):
1346
+ r"""
1347
+ Iterate over the component intervals is ascending order.
1348
+
1349
+ OUTPUT: an iterator over the intervals
1350
+
1351
+ EXAMPLES::
1352
+
1353
+ sage: s = RealSet(RealSet.open_closed(0,1), RealSet.closed_open(2,3))
1354
+ sage: i = iter(s)
1355
+ sage: next(i)
1356
+ (0, 1]
1357
+ sage: next(i)
1358
+ [2, 3)
1359
+ """
1360
+ return iter(self._intervals)
1361
+
1362
+ def n_components(self):
1363
+ r"""
1364
+ Return the number of connected components.
1365
+
1366
+ See also :meth:`get_interval`.
1367
+
1368
+ EXAMPLES::
1369
+
1370
+ sage: s = RealSet(RealSet.open_closed(0,1), RealSet.closed_open(2,3))
1371
+ sage: s.n_components()
1372
+ 2
1373
+ """
1374
+ return len(self._intervals)
1375
+
1376
+ def cardinality(self):
1377
+ r"""
1378
+ Return the cardinality of the subset of the real line.
1379
+
1380
+ OUTPUT:
1381
+
1382
+ Integer or infinity; the size of a discrete set is the number
1383
+ of points; the size of a real interval is Infinity.
1384
+
1385
+ EXAMPLES::
1386
+
1387
+ sage: RealSet([0, 0], [1, 1], [3, 3]).cardinality()
1388
+ 3
1389
+ sage: RealSet(0,3).cardinality()
1390
+ +Infinity
1391
+ """
1392
+ n = ZZ(0)
1393
+ for interval in self._intervals:
1394
+ if interval.is_point():
1395
+ n += 1
1396
+ else:
1397
+ return infinity
1398
+ return n
1399
+
1400
+ def is_empty(self):
1401
+ r"""
1402
+ Return whether the set is empty.
1403
+
1404
+ EXAMPLES::
1405
+
1406
+ sage: RealSet(0, 1).is_empty()
1407
+ False
1408
+ sage: RealSet(0, 0).is_empty()
1409
+ True
1410
+ sage: RealSet.interval(1, 1, lower_closed=False, upper_closed=True).is_empty()
1411
+ True
1412
+ sage: RealSet.interval(1, -1, lower_closed=False, upper_closed=True).is_empty()
1413
+ False
1414
+ """
1415
+ return len(self._intervals) == 0
1416
+
1417
+ def is_universe(self):
1418
+ r"""
1419
+ Return whether the set is the ambient space (the real line).
1420
+
1421
+ EXAMPLES::
1422
+
1423
+ sage: RealSet().ambient().is_universe()
1424
+ True
1425
+ """
1426
+ return self == self.ambient()
1427
+
1428
+ def get_interval(self, i):
1429
+ r"""
1430
+ Return the ``i``-th connected component.
1431
+
1432
+ Note that the intervals representing the real set are always
1433
+ normalized, i.e., they are sorted, disjoint and not connected.
1434
+
1435
+ INPUT:
1436
+
1437
+ - ``i`` -- integer
1438
+
1439
+ OUTPUT: the `i`-th connected component as a :class:`InternalRealInterval`
1440
+
1441
+ EXAMPLES::
1442
+
1443
+ sage: s = RealSet(RealSet.open_closed(0,1), RealSet.closed_open(2,3))
1444
+ sage: s.get_interval(0)
1445
+ (0, 1]
1446
+ sage: s[0] # shorthand
1447
+ (0, 1]
1448
+ sage: s.get_interval(1)
1449
+ [2, 3)
1450
+ sage: s[0] == s.get_interval(0)
1451
+ True
1452
+ """
1453
+ return self._intervals[i]
1454
+
1455
+ __getitem__ = get_interval
1456
+
1457
+ def __bool__(self):
1458
+ r"""
1459
+ A set is considered ``True`` unless it is empty, in which case it is
1460
+ considered to be ``False``.
1461
+
1462
+ EXAMPLES::
1463
+
1464
+ sage: bool(RealSet(0, 1))
1465
+ True
1466
+ sage: bool(RealSet())
1467
+ False
1468
+ """
1469
+ return not self.is_empty()
1470
+
1471
+ # ParentMethods of Subobjects
1472
+
1473
+ def ambient(self):
1474
+ r"""
1475
+ Return the ambient space (the real line).
1476
+
1477
+ EXAMPLES::
1478
+
1479
+ sage: s = RealSet(RealSet.open_closed(0,1), RealSet.closed_open(2,3))
1480
+ sage: s.ambient()
1481
+ (-oo, +oo)
1482
+ """
1483
+ return RealSet.real_line()
1484
+
1485
+ def lift(self, x):
1486
+ r"""
1487
+ Lift ``x`` to the ambient space for ``self``.
1488
+
1489
+ This version of the method just returns ``x``.
1490
+
1491
+ EXAMPLES::
1492
+
1493
+ sage: s = RealSet(0, 2); s
1494
+ (0, 2)
1495
+ sage: s.lift(1)
1496
+ 1
1497
+ """
1498
+ return x
1499
+
1500
+ def retract(self, x):
1501
+ r"""
1502
+ Retract ``x`` to ``self``.
1503
+
1504
+ It raises an error if ``x`` does not lie in the set ``self``.
1505
+
1506
+ EXAMPLES::
1507
+
1508
+ sage: s = RealSet(0, 2); s
1509
+ (0, 2)
1510
+ sage: s.retract(1)
1511
+ 1
1512
+ sage: s.retract(2)
1513
+ Traceback (most recent call last):
1514
+ ...
1515
+ ValueError: 2 is not an element of (0, 2)
1516
+ """
1517
+ if x not in self:
1518
+ raise ValueError(f'{x} is not an element of {self}')
1519
+ return x
1520
+
1521
+ def normalize(intervals):
1522
+ r"""
1523
+ Bring a collection of intervals into canonical form.
1524
+
1525
+ INPUT:
1526
+
1527
+ - ``intervals`` -- list/tuple/iterable of intervals
1528
+
1529
+ OUTPUT: a tuple of intervals such that
1530
+
1531
+ * they are sorted in ascending order (by lower bound)
1532
+
1533
+ * there is a gap between each interval
1534
+
1535
+ * all intervals are non-empty
1536
+
1537
+ EXAMPLES::
1538
+
1539
+ sage: i1 = RealSet((0, 1))[0]
1540
+ sage: i2 = RealSet([1, 2])[0]
1541
+ sage: i3 = RealSet((2, 3))[0]
1542
+ sage: RealSet.normalize([i1, i2, i3])
1543
+ ((0, 3),)
1544
+ """
1545
+ scan = merge(*[[i._scan_lower(), i._scan_upper()] for i in intervals])
1546
+ union_intervals = tuple(RealSet._scan_to_intervals(scan, lambda i: i > 0))
1547
+ return union_intervals
1548
+
1549
+ def _repr_(self):
1550
+ r"""
1551
+ Return a string representation of ``self``.
1552
+
1553
+ OUTPUT: string representation
1554
+
1555
+ EXAMPLES::
1556
+
1557
+ sage: RealSet(0, 1)._repr_()
1558
+ '(0, 1)'
1559
+ """
1560
+ if self.n_components() == 0:
1561
+ return '{}'
1562
+ else:
1563
+ return ' ∪ '.join(map(repr, self._intervals))
1564
+
1565
+ def _latex_(self):
1566
+ r"""
1567
+ Return a latex representation of ``self``.
1568
+
1569
+ EXAMPLES::
1570
+
1571
+ sage: latex(RealSet(0, 1))
1572
+ (0, 1)
1573
+ sage: latex((RealSet(0, 1).union(RealSet.unbounded_above_closed(2))))
1574
+ (0, 1) \cup [2, +\infty)
1575
+ """
1576
+ from sage.misc.latex import latex
1577
+ if self.n_components() == 0:
1578
+ return r'\emptyset'
1579
+ else:
1580
+ return r' \cup '.join(latex(i) for i in self._intervals)
1581
+
1582
+ def _sympy_condition_(self, variable):
1583
+ r"""
1584
+ Convert to a sympy conditional expression.
1585
+
1586
+ INPUT:
1587
+
1588
+ - ``variable`` -- a symbolic variable
1589
+
1590
+ EXAMPLES::
1591
+
1592
+ sage: # needs sage.symbolic
1593
+ sage: RealSet(0, 1)._sympy_condition_(x)
1594
+ (0 < x) & (x < 1)
1595
+ sage: RealSet((0,1), [2,3])._sympy_condition_(x)
1596
+ ((2 <= x) & (x <= 3)) | ((0 < x) & (x < 1))
1597
+ sage: RealSet.unbounded_below_open(0)._sympy_condition_(x)
1598
+ x < 0
1599
+ sage: RealSet.unbounded_above_closed(2)._sympy_condition_(x)
1600
+ 2 <= x
1601
+
1602
+ TESTS::
1603
+
1604
+ sage: RealSet(6,6)._sympy_condition_(x) # needs sympy sage.symbolic
1605
+ False
1606
+ sage: RealSet([6,6])._sympy_condition_(x) # needs sympy sage.symbolic
1607
+ Eq(x, 6)
1608
+ """
1609
+ x = variable
1610
+ false = (x == 0)._sympy_() & False # trick to get sympy's False
1611
+ if self.n_components() == 0:
1612
+ return false
1613
+ else:
1614
+ cond = false
1615
+ for it in self._intervals:
1616
+ cond = cond | it._sympy_condition_(x)
1617
+ return cond
1618
+
1619
+ def _giac_condition_(self, variable):
1620
+ r"""
1621
+ Convert to a Giac conditional expression.
1622
+
1623
+ INPUT:
1624
+
1625
+ - ``variable`` -- a symbolic variable
1626
+
1627
+ EXAMPLES::
1628
+
1629
+ sage: # needs sage.libs.giac
1630
+ sage: RealSet(0, 1)._giac_condition_(x)
1631
+ '((0 < sageVARx) and (sageVARx < 1))'
1632
+ sage: RealSet((0,1), [2,3])._giac_condition_(x)
1633
+ '((0 < sageVARx) and (sageVARx < 1)) or ((2 <= sageVARx) and (sageVARx <= 3))'
1634
+ sage: RealSet.unbounded_below_open(0)._giac_condition_(x)
1635
+ '((true) and (sageVARx < 0))'
1636
+ sage: RealSet.unbounded_above_closed(2)._giac_condition_(x)
1637
+ '((2 <= sageVARx) and (true))'
1638
+
1639
+ TESTS::
1640
+
1641
+ sage: RealSet(6,6)._giac_condition_(x) # needs sage.libs.giac
1642
+ 'false'
1643
+ sage: RealSet([6,6])._giac_condition_(x) # needs sage.libs.giac
1644
+ 'sageVARx == 6'
1645
+ """
1646
+ x = variable
1647
+ false = 'false'
1648
+ if self.n_components() == 0:
1649
+ return false
1650
+ return ' or '.join(it._giac_condition_(x)
1651
+ for it in self._intervals)
1652
+
1653
+ @staticmethod
1654
+ def _prep(lower, upper=None):
1655
+ r"""
1656
+ Helper to prepare the lower and upper bounds.
1657
+
1658
+ EXAMPLES::
1659
+
1660
+ sage: RealSet._prep(1, 0)
1661
+ (0, 1)
1662
+ sage: RealSet._prep(-oo,+oo)
1663
+ (-Infinity, +Infinity)
1664
+ sage: RealSet._prep(oo)
1665
+ +Infinity
1666
+ """
1667
+ if lower == minus_infinity:
1668
+ lower = minus_infinity
1669
+ elif lower == infinity:
1670
+ lower = infinity
1671
+ else:
1672
+ lower = RLF(lower)
1673
+ if upper is None:
1674
+ return lower
1675
+ if upper == minus_infinity:
1676
+ upper = minus_infinity
1677
+ elif upper == infinity:
1678
+ upper = infinity
1679
+ else:
1680
+ upper = RLF(upper)
1681
+ if upper is infinity or lower is minus_infinity:
1682
+ return lower, upper
1683
+ elif lower is infinity or upper is minus_infinity:
1684
+ return upper, lower
1685
+ elif upper < lower:
1686
+ return upper, lower
1687
+ else:
1688
+ return lower, upper
1689
+
1690
+ @staticmethod
1691
+ def interval(lower, upper, *, lower_closed=None, upper_closed=None, **kwds):
1692
+ r"""
1693
+ Construct an interval.
1694
+
1695
+ INPUT:
1696
+
1697
+ - ``lower``, ``upper`` -- two real numbers or infinity; they
1698
+ will be sorted if necessary
1699
+
1700
+ - ``lower_closed``, ``upper_closed`` -- boolean; whether the interval
1701
+ is closed at the lower and upper bound of the interval, respectively
1702
+
1703
+ - ``**kwds`` -- see :class:`RealSet`
1704
+
1705
+ OUTPUT: a new :class:`RealSet`
1706
+
1707
+ EXAMPLES::
1708
+
1709
+ sage: RealSet.interval(1, 0, lower_closed=True, upper_closed=False)
1710
+ [0, 1)
1711
+ """
1712
+ if lower_closed is None or upper_closed is None:
1713
+ raise ValueError('lower_closed and upper_closed must be explicitly given')
1714
+ lower, upper = RealSet._prep(lower, upper)
1715
+ return RealSet(InternalRealInterval(lower, lower_closed, upper, upper_closed), **kwds)
1716
+
1717
+ @staticmethod
1718
+ def open(lower, upper, **kwds):
1719
+ r"""
1720
+ Construct an open interval.
1721
+
1722
+ INPUT:
1723
+
1724
+ - ``lower``, ``upper`` -- two real numbers or infinity; they
1725
+ will be sorted if necessary
1726
+
1727
+ - ``**kwds`` -- see :class:`RealSet`
1728
+
1729
+ OUTPUT: a new :class:`RealSet`
1730
+
1731
+ EXAMPLES::
1732
+
1733
+ sage: RealSet.open(1, 0)
1734
+ (0, 1)
1735
+ """
1736
+ lower, upper = RealSet._prep(lower, upper)
1737
+ return RealSet(InternalRealInterval(lower, False, upper, False), **kwds)
1738
+
1739
+ @staticmethod
1740
+ def closed(lower, upper, **kwds):
1741
+ r"""
1742
+ Construct a closed interval.
1743
+
1744
+ INPUT:
1745
+
1746
+ - ``lower``, ``upper`` -- two real numbers or infinity; they
1747
+ will be sorted if necessary
1748
+
1749
+ - ``**kwds`` -- see :class:`RealSet`
1750
+
1751
+ OUTPUT: a new :class:`RealSet`
1752
+
1753
+ EXAMPLES::
1754
+
1755
+ sage: RealSet.closed(1, 0)
1756
+ [0, 1]
1757
+ """
1758
+ lower, upper = RealSet._prep(lower, upper)
1759
+ return RealSet(InternalRealInterval(lower, True, upper, True), **kwds)
1760
+
1761
+ @staticmethod
1762
+ def point(p, **kwds):
1763
+ r"""
1764
+ Construct an interval containing a single point.
1765
+
1766
+ INPUT:
1767
+
1768
+ - ``p`` -- a real number
1769
+
1770
+ - ``**kwds`` -- see :class:`RealSet`
1771
+
1772
+ OUTPUT: a new :class:`RealSet`
1773
+
1774
+ EXAMPLES::
1775
+
1776
+ sage: RealSet.open(1, 0)
1777
+ (0, 1)
1778
+ """
1779
+ p = RealSet._prep(p)
1780
+ return RealSet(InternalRealInterval(p, True, p, True), **kwds)
1781
+
1782
+ @staticmethod
1783
+ def open_closed(lower, upper, **kwds):
1784
+ r"""
1785
+ Construct a half-open interval.
1786
+
1787
+ INPUT:
1788
+
1789
+ - ``lower``, ``upper`` -- two real numbers or infinity; they
1790
+ will be sorted if necessary
1791
+
1792
+ - ``**kwds`` -- see :class:`RealSet`
1793
+
1794
+ OUTPUT:
1795
+
1796
+ A new :class:`RealSet` that is open at the lower bound and
1797
+ closed at the upper bound.
1798
+
1799
+ EXAMPLES::
1800
+
1801
+ sage: RealSet.open_closed(1, 0)
1802
+ (0, 1]
1803
+ """
1804
+ lower, upper = RealSet._prep(lower, upper)
1805
+ return RealSet(InternalRealInterval(lower, False, upper, True), **kwds)
1806
+
1807
+ @staticmethod
1808
+ def closed_open(lower, upper, **kwds):
1809
+ r"""
1810
+ Construct a half-open interval.
1811
+
1812
+ INPUT:
1813
+
1814
+ - ``lower``, ``upper`` -- two real numbers or infinity; they
1815
+ will be sorted if necessary
1816
+
1817
+ - ``**kwds`` -- see :class:`RealSet`
1818
+
1819
+ OUTPUT:
1820
+
1821
+ A new :class:`RealSet` that is closed at the lower bound and
1822
+ open at the upper bound.
1823
+
1824
+ EXAMPLES::
1825
+
1826
+ sage: RealSet.closed_open(1, 0)
1827
+ [0, 1)
1828
+ """
1829
+ lower, upper = RealSet._prep(lower, upper)
1830
+ return RealSet(InternalRealInterval(lower, True, upper, False), **kwds)
1831
+
1832
+ @staticmethod
1833
+ def unbounded_below_closed(bound, **kwds):
1834
+ r"""
1835
+ Construct a semi-infinite interval.
1836
+
1837
+ INPUT:
1838
+
1839
+ - ``bound`` -- a real number
1840
+
1841
+ OUTPUT:
1842
+
1843
+ A new :class:`RealSet` from minus infinity to the bound (including).
1844
+
1845
+ - ``**kwds`` -- see :class:`RealSet`
1846
+
1847
+ EXAMPLES::
1848
+
1849
+ sage: RealSet.unbounded_below_closed(1)
1850
+ (-oo, 1]
1851
+ """
1852
+ bound = RealSet._prep(bound)
1853
+ return RealSet(InternalRealInterval(minus_infinity, False, bound, True), **kwds)
1854
+
1855
+ @staticmethod
1856
+ def unbounded_below_open(bound, **kwds):
1857
+ r"""
1858
+ Construct a semi-infinite interval.
1859
+
1860
+ INPUT:
1861
+
1862
+ - ``bound`` -- a real number
1863
+
1864
+ OUTPUT:
1865
+
1866
+ A new :class:`RealSet` from minus infinity to the bound (excluding).
1867
+
1868
+ - ``**kwds`` -- see :class:`RealSet`
1869
+
1870
+ EXAMPLES::
1871
+
1872
+ sage: RealSet.unbounded_below_open(1)
1873
+ (-oo, 1)
1874
+ """
1875
+ bound = RealSet._prep(bound)
1876
+ return RealSet(InternalRealInterval(minus_infinity, False, RLF(bound), False), **kwds)
1877
+
1878
+ @staticmethod
1879
+ def unbounded_above_closed(bound, **kwds):
1880
+ r"""
1881
+ Construct a semi-infinite interval.
1882
+
1883
+ INPUT:
1884
+
1885
+ - ``bound`` -- a real number
1886
+
1887
+ - ``**kwds`` -- see :class:`RealSet`
1888
+
1889
+ OUTPUT:
1890
+
1891
+ A new :class:`RealSet` from the bound (including) to plus
1892
+ infinity.
1893
+
1894
+ EXAMPLES::
1895
+
1896
+ sage: RealSet.unbounded_above_closed(1)
1897
+ [1, +oo)
1898
+ """
1899
+ bound = RealSet._prep(bound)
1900
+ return RealSet(InternalRealInterval(RLF(bound), True, infinity, False), **kwds)
1901
+
1902
+ @staticmethod
1903
+ def unbounded_above_open(bound, **kwds):
1904
+ r"""
1905
+ Construct a semi-infinite interval.
1906
+
1907
+ INPUT:
1908
+
1909
+ - ``bound`` -- a real number
1910
+
1911
+ - ``**kwds`` -- see :class:`RealSet`
1912
+
1913
+ OUTPUT:
1914
+
1915
+ A new :class:`RealSet` from the bound (excluding) to plus
1916
+ infinity.
1917
+
1918
+ EXAMPLES::
1919
+
1920
+ sage: RealSet.unbounded_above_open(1)
1921
+ (1, +oo)
1922
+ """
1923
+ bound = RealSet._prep(bound)
1924
+ return RealSet(InternalRealInterval(RLF(bound), False, infinity, False), **kwds)
1925
+
1926
+ @staticmethod
1927
+ def real_line(**kwds):
1928
+ r"""
1929
+ Construct the real line.
1930
+
1931
+ INPUT:
1932
+
1933
+ - ``**kwds`` -- see :class:`RealSet`
1934
+
1935
+ EXAMPLES::
1936
+
1937
+ sage: RealSet.real_line()
1938
+ (-oo, +oo)
1939
+ """
1940
+ return RealSet(InternalRealInterval(minus_infinity, False, infinity, False), **kwds)
1941
+
1942
+ def _scan(self):
1943
+ r"""
1944
+ Helper function for the scan-line method of :class:`RealSet`.
1945
+
1946
+ OUTPUT:
1947
+
1948
+ Generate events of the form ``(x, epsilon), delta``
1949
+ for each boundary point ``x`` of ``self``.
1950
+
1951
+ When ``x`` is the beginning of an interval ('on'):
1952
+
1953
+ - ``epsilon`` is 0 if the interval is lower closed and 1 otherwise,
1954
+ - ``delta`` is -1
1955
+
1956
+ When ``x`` is the end of an interval ('off'):
1957
+
1958
+ - ``epsilon`` is 1 if the interval is upper closed and 0 otherwise,
1959
+ - ``delta`` is +1
1960
+
1961
+ This is so that the events sort lexicographically in a way that if
1962
+ we have intervals whose closures intersect in one point, such as
1963
+ [a, b) and [b, c], we see first the 'on' event and then the 'off'
1964
+ event. In this way consumers of the scan can easily implement merging
1965
+ of such intervals.
1966
+
1967
+ EXAMPLES::
1968
+
1969
+ sage: s = RealSet((-oo,0), RealSet.open_closed(0, 1), (2, 3), [4, 5], [5, 5], (6, oo)); s
1970
+ (-oo, 0) ∪ (0, 1] ∪ (2, 3) ∪ [4, 5] ∪ (6, +oo)
1971
+ sage: list(s._scan())
1972
+ [((-Infinity, 1), -1),
1973
+ ((0, 0), 1),
1974
+ ((0, 1), -1),
1975
+ ((1, 1), 1),
1976
+ ((2, 1), -1),
1977
+ ((3, 0), 1),
1978
+ ((4, 0), -1),
1979
+ ((5, 1), 1),
1980
+ ((6, 1), -1),
1981
+ ((+Infinity, 0), 1)]
1982
+ """
1983
+ for i in self._intervals:
1984
+ yield i._scan_lower()
1985
+ yield i._scan_upper()
1986
+
1987
+ @staticmethod
1988
+ def _scan_to_intervals(scan, condition):
1989
+ r"""
1990
+ Helper function for the scan-line method of :class:`RealSet`.
1991
+
1992
+ INPUT:
1993
+
1994
+ - ``scan`` -- a generator/list/tuple/iterable of events of the form
1995
+ ``(x, epsilon), delta``, see :meth:`_scan`
1996
+ - ``condition`` -- a function indicating the on or off boundary points
1997
+
1998
+ OUTPUT: generate :class:`InternalRealInterval` objects
1999
+
2000
+ EXAMPLES::
2001
+
2002
+ sage: s = RealSet((-oo,0), RealSet.open_closed(0, 1), (2, 3), [4, 5], [5, 5], (6, oo)); s
2003
+ (-oo, 0) ∪ (0, 1] ∪ (2, 3) ∪ [4, 5] ∪ (6, +oo)
2004
+ sage: scan = list(s._scan()); scan
2005
+ [((-Infinity, 1), -1),
2006
+ ((0, 0), 1),
2007
+ ((0, 1), -1),
2008
+ ((1, 1), 1),
2009
+ ((2, 1), -1),
2010
+ ((3, 0), 1),
2011
+ ((4, 0), -1),
2012
+ ((5, 1), 1),
2013
+ ((6, 1), -1),
2014
+ ((+Infinity, 0), 1)]
2015
+ sage: list(RealSet._scan_to_intervals(scan, lambda i: i > 0))
2016
+ [(-oo, 0), (0, 1], (2, 3), [4, 5], (6, +oo)]
2017
+ """
2018
+ indicator = 0
2019
+ (on_x, on_epsilon) = (None, None)
2020
+ was_on = False
2021
+ for event in scan:
2022
+ (x, epsilon), delta = event
2023
+ indicator -= delta
2024
+ now_on = condition(indicator)
2025
+ if not was_on and now_on: # switched on
2026
+ (on_x, on_epsilon) = (x, epsilon)
2027
+ elif was_on and not now_on: # switched off
2028
+ if (on_x, on_epsilon) < (x, epsilon):
2029
+ lower_closed = on_epsilon == 0
2030
+ upper_closed = epsilon > 0
2031
+ yield InternalRealInterval(on_x, lower_closed, x, upper_closed)
2032
+ was_on = now_on
2033
+
2034
+ def union(self, *real_set_collection):
2035
+ """
2036
+ Return the union of real sets.
2037
+
2038
+ INPUT:
2039
+
2040
+ - ``*real_set_collection`` -- list/tuple/iterable of :class:`RealSet`
2041
+ or data that defines one
2042
+
2043
+ OUTPUT: the set-theoretic union as a new :class:`RealSet`
2044
+
2045
+ EXAMPLES::
2046
+
2047
+ sage: s1 = RealSet(0,2)
2048
+ sage: s2 = RealSet(1,3)
2049
+ sage: s1.union(s2)
2050
+ (0, 3)
2051
+ sage: s1.union(1,3)
2052
+ (0, 3)
2053
+ sage: s1 | s2 # syntactic sugar
2054
+ (0, 3)
2055
+ sage: s1 + s2 # syntactic sugar
2056
+ (0, 3)
2057
+ sage: RealSet().union(RealSet.real_line())
2058
+ (-oo, +oo)
2059
+ sage: s = RealSet().union([1, 2], (2, 3)); s
2060
+ [1, 3)
2061
+ sage: RealSet().union((-oo, 0), x > 6, s[0], # needs sage.symbolic
2062
+ ....: RealSet.point(5.0), RealSet.closed_open(2, 4))
2063
+ (-oo, 0) ∪ [1, 4) ∪ {5} ∪ (6, +oo)
2064
+ """
2065
+ sets = [self]
2066
+ if len(real_set_collection) == 1 and isinstance(real_set_collection[0], RealSet):
2067
+ sets.append(real_set_collection[0])
2068
+ elif len(real_set_collection) == 2:
2069
+ a, b = real_set_collection
2070
+ # allow self.union(0,1) syntax
2071
+ try:
2072
+ a.n()
2073
+ b.n()
2074
+ sets.append(RealSet(a, b))
2075
+ except (AttributeError, ValueError, TypeError):
2076
+ sets.append(RealSet(a))
2077
+ sets.append(RealSet(b))
2078
+ else:
2079
+ sets.extend([RealSet(_) for _ in real_set_collection])
2080
+ # Same as return RealSet(*real_set_collection). The following is a bit
2081
+ # better when the input consists of RealSets, since they are normalized
2082
+ scan = merge(*[real_set._scan() for real_set in sets])
2083
+ intervals = tuple(RealSet._scan_to_intervals(scan, lambda i: i > 0))
2084
+ return RealSet(*intervals, normalized=True)
2085
+
2086
+ def intersection(self, *real_set_collection):
2087
+ """
2088
+ Return the intersection of real sets.
2089
+
2090
+ INPUT:
2091
+
2092
+ - ``*real_set_collection`` -- list/tuple/iterable of :class:`RealSet`
2093
+ or data that defines one
2094
+
2095
+ OUTPUT: the set-theoretic intersection as a new :class:`RealSet`
2096
+
2097
+ EXAMPLES::
2098
+
2099
+ sage: s1 = RealSet(0,2) + RealSet.unbounded_above_closed(10); s1
2100
+ (0, 2) ∪ [10, +oo)
2101
+ sage: s2 = RealSet(1,3) + RealSet.unbounded_below_closed(-10); s2
2102
+ (-oo, -10] ∪ (1, 3)
2103
+ sage: s1.intersection(s2)
2104
+ (1, 2)
2105
+ sage: s1 & s2 # syntactic sugar
2106
+ (1, 2)
2107
+ sage: s3 = RealSet((0, 1), (2, 3)); s3
2108
+ (0, 1) ∪ (2, 3)
2109
+ sage: s4 = RealSet([0, 1], [2, 3]); s4
2110
+ [0, 1] ∪ [2, 3]
2111
+ sage: s3.intersection(s4)
2112
+ (0, 1) ∪ (2, 3)
2113
+ sage: s3.intersection([1, 2])
2114
+ {}
2115
+ sage: s4.intersection([1, 2])
2116
+ {1} ∪ {2}
2117
+ sage: s4.intersection(1, 2)
2118
+ {}
2119
+ sage: s5 = RealSet.closed_open(1, 10); s5
2120
+ [1, 10)
2121
+ sage: s5.intersection(-oo, +oo)
2122
+ [1, 10)
2123
+ sage: s5.intersection(x != 2, (-oo, 3), RealSet.real_line()[0]) # needs sage.symbolic
2124
+ [1, 2) ∪ (2, 3)
2125
+
2126
+ TESTS::
2127
+
2128
+ sage: s1 = RealSet([1, 2])
2129
+ sage: s2 = RealSet([2, 3])
2130
+ sage: s3 = RealSet(3, 4)
2131
+ sage: s4 = RealSet.closed_open(4, 5)
2132
+ sage: s5 = RealSet(5, 6)
2133
+ sage: s1.intersection(RealSet())
2134
+ {}
2135
+ sage: s1.intersection(s2)
2136
+ {2}
2137
+ sage: s2.intersection(s3)
2138
+ {}
2139
+ sage: s3.intersection(s4)
2140
+ {}
2141
+ sage: s4.intersection(s5)
2142
+ {}
2143
+ """
2144
+ sets = [self]
2145
+ if len(real_set_collection) == 1 and isinstance(real_set_collection[0], RealSet):
2146
+ sets.append(real_set_collection[0])
2147
+ elif len(real_set_collection) == 2:
2148
+ a, b = real_set_collection
2149
+ # allow self.intersection(0,1) syntax
2150
+ try:
2151
+ a.n()
2152
+ b.n()
2153
+ sets.append(RealSet(a, b))
2154
+ except (AttributeError, ValueError, TypeError):
2155
+ sets.append(RealSet(a))
2156
+ sets.append(RealSet(b))
2157
+ else:
2158
+ sets.extend([RealSet(_) for _ in real_set_collection])
2159
+ n = len(sets)
2160
+ scan = merge(*[real_set._scan() for real_set in sets])
2161
+ intervals = tuple(RealSet._scan_to_intervals(scan, lambda i: i == n))
2162
+ return RealSet(*intervals, normalized=True)
2163
+
2164
+ def inf(self):
2165
+ """
2166
+ Return the infimum.
2167
+
2168
+ OUTPUT: a real number or infinity
2169
+
2170
+ EXAMPLES::
2171
+
2172
+ sage: s1 = RealSet(0,2) + RealSet.unbounded_above_closed(10); s1
2173
+ (0, 2) ∪ [10, +oo)
2174
+ sage: s1.inf()
2175
+ 0
2176
+
2177
+ sage: s2 = RealSet(1,3) + RealSet.unbounded_below_closed(-10); s2
2178
+ (-oo, -10] ∪ (1, 3)
2179
+ sage: s2.inf()
2180
+ -Infinity
2181
+ """
2182
+ if self.n_components() == 0:
2183
+ return infinity
2184
+ return self._intervals[0].lower()
2185
+
2186
+ def sup(self):
2187
+ """
2188
+ Return the supremum.
2189
+
2190
+ OUTPUT: a real number or infinity
2191
+
2192
+ EXAMPLES::
2193
+
2194
+ sage: s1 = RealSet(0,2) + RealSet.unbounded_above_closed(10); s1
2195
+ (0, 2) ∪ [10, +oo)
2196
+ sage: s1.sup()
2197
+ +Infinity
2198
+
2199
+ sage: s2 = RealSet(1,3) + RealSet.unbounded_below_closed(-10); s2
2200
+ (-oo, -10] ∪ (1, 3)
2201
+ sage: s2.sup()
2202
+ 3
2203
+ """
2204
+ if self.n_components() == 0:
2205
+ return minus_infinity
2206
+ return self._intervals[-1].upper()
2207
+
2208
+ def complement(self):
2209
+ """
2210
+ Return the complement.
2211
+
2212
+ OUTPUT: the set-theoretic complement as a new :class:`RealSet`
2213
+
2214
+ EXAMPLES::
2215
+
2216
+ sage: RealSet(0,1).complement()
2217
+ (-oo, 0] ∪ [1, +oo)
2218
+
2219
+ sage: s1 = RealSet(0,2) + RealSet.unbounded_above_closed(10); s1
2220
+ (0, 2) ∪ [10, +oo)
2221
+ sage: s1.complement()
2222
+ (-oo, 0] ∪ [2, 10)
2223
+
2224
+ sage: s2 = RealSet(1,3) + RealSet.unbounded_below_closed(-10); s2
2225
+ (-oo, -10] ∪ (1, 3)
2226
+ sage: s2.complement()
2227
+ (-10, 1] ∪ [3, +oo)
2228
+
2229
+ TESTS::
2230
+
2231
+ sage: RealSet(x != 0).complement() # needs sage.symbolic
2232
+ {0}
2233
+ sage: RealSet.real_line().complement()
2234
+ {}
2235
+ sage: _.complement()
2236
+ (-oo, +oo)
2237
+ """
2238
+ return (self.ambient()).difference(self)
2239
+
2240
+ def difference(self, *other):
2241
+ """
2242
+ Return ``self`` with ``other`` subtracted.
2243
+
2244
+ INPUT:
2245
+
2246
+ - ``other`` -- a :class:`RealSet` or data that defines one
2247
+
2248
+ OUTPUT:
2249
+
2250
+ The set-theoretic difference of ``self`` with ``other``
2251
+ removed as a new :class:`RealSet`.
2252
+
2253
+ EXAMPLES::
2254
+
2255
+ sage: s1 = RealSet(0,2) + RealSet.unbounded_above_closed(10); s1
2256
+ (0, 2) ∪ [10, +oo)
2257
+ sage: s2 = RealSet(1,3) + RealSet.unbounded_below_closed(-10); s2
2258
+ (-oo, -10] ∪ (1, 3)
2259
+ sage: s1.difference(s2)
2260
+ (0, 1] ∪ [10, +oo)
2261
+ sage: s1 - s2 # syntactic sugar
2262
+ (0, 1] ∪ [10, +oo)
2263
+ sage: s2.difference(s1)
2264
+ (-oo, -10] ∪ [2, 3)
2265
+ sage: s2 - s1 # syntactic sugar
2266
+ (-oo, -10] ∪ [2, 3)
2267
+ sage: s1.difference(1,11)
2268
+ (0, 1] ∪ [11, +oo)
2269
+ """
2270
+ remove = [(pt, -delta) for (pt, delta) in RealSet(*other)._scan()]
2271
+ # Note: flip delta for boundary point in the removed set.
2272
+ # turn-on lower open becomes turn-off upper closed.
2273
+ scan = merge(self._scan(), remove)
2274
+ # Because the negative delta, indicator in def _scan_to_intervals can be negative.
2275
+ intervals = tuple(RealSet._scan_to_intervals(scan, lambda i: i > 0))
2276
+ return RealSet(*intervals, normalized=True)
2277
+
2278
+ def symmetric_difference(self, *other):
2279
+ r"""
2280
+ Return the symmetric difference of ``self`` and ``other``.
2281
+
2282
+ INPUT:
2283
+
2284
+ - ``other`` -- a :class:`RealSet` or data that defines one
2285
+
2286
+ OUTPUT:
2287
+
2288
+ The set-theoretic symmetric difference of ``self`` and ``other``
2289
+ as a new :class:`RealSet`.
2290
+
2291
+ EXAMPLES::
2292
+
2293
+ sage: s1 = RealSet(0,2); s1
2294
+ (0, 2)
2295
+ sage: s2 = RealSet.unbounded_above_open(1); s2
2296
+ (1, +oo)
2297
+ sage: s1.symmetric_difference(s2)
2298
+ (0, 1] ∪ [2, +oo)
2299
+ """
2300
+ scan = merge(self._scan(), RealSet(*other)._scan())
2301
+ intervals = tuple(RealSet._scan_to_intervals(scan, lambda i: i == 1))
2302
+ return RealSet(*intervals, normalized=True)
2303
+
2304
+ def contains(self, x):
2305
+ """
2306
+ Return whether `x` is contained in the set.
2307
+
2308
+ INPUT:
2309
+
2310
+ - ``x`` -- a real number
2311
+
2312
+ OUTPUT: boolean
2313
+
2314
+ EXAMPLES::
2315
+
2316
+ sage: s = RealSet(0,2) + RealSet.unbounded_above_closed(10); s
2317
+ (0, 2) ∪ [10, +oo)
2318
+ sage: s.contains(1)
2319
+ True
2320
+ sage: s.contains(0)
2321
+ False
2322
+ sage: s.contains(10.0)
2323
+ True
2324
+ sage: 10 in s # syntactic sugar
2325
+ True
2326
+ sage: s.contains(+oo)
2327
+ False
2328
+ sage: RealSet().contains(1)
2329
+ False
2330
+ """
2331
+ x = RLF(x)
2332
+ for interval in self._intervals:
2333
+ if interval.contains(x):
2334
+ return True
2335
+ return False
2336
+
2337
+ __contains__ = contains
2338
+
2339
+ def is_subset(self, *other):
2340
+ r"""
2341
+ Return whether ``self`` is a subset of ``other``.
2342
+
2343
+ INPUT:
2344
+
2345
+ - ``*other`` -- a :class:`RealSet` or something that defines one
2346
+
2347
+ OUTPUT: boolean
2348
+
2349
+ EXAMPLES::
2350
+
2351
+ sage: I = RealSet((1,2))
2352
+ sage: J = RealSet((1,3))
2353
+ sage: K = RealSet((2,3))
2354
+ sage: I.is_subset(J)
2355
+ True
2356
+ sage: J.is_subset(K)
2357
+ False
2358
+ """
2359
+ return RealSet(*other).intersection(self) == self
2360
+
2361
+ is_included_in = deprecated_function_alias(31927, is_subset)
2362
+
2363
+ def _an_element_(self):
2364
+ """
2365
+ Return a point of the set.
2366
+
2367
+ OUTPUT: a real number
2368
+
2369
+ It raises an :class:`~sage.categories.sets_cat.EmptySetError` if the set is empty.
2370
+
2371
+ EXAMPLES::
2372
+
2373
+ sage: RealSet.open_closed(0, 1).an_element()
2374
+ 1
2375
+ sage: RealSet(0, 1).an_element()
2376
+ 1/2
2377
+ sage: RealSet(-oo,+oo).an_element()
2378
+ 0
2379
+ sage: RealSet(-oo,7).an_element()
2380
+ 6
2381
+ sage: RealSet(7,+oo).an_element()
2382
+ 8
2383
+ sage: RealSet().an_element()
2384
+ Traceback (most recent call last):
2385
+ ...
2386
+ sage.categories.sets_cat.EmptySetError
2387
+ """
2388
+ from sage.rings.infinity import AnInfinity
2389
+ if not self._intervals:
2390
+ raise EmptySetError
2391
+ i = self._intervals[0]
2392
+ if isinstance(i.lower(), AnInfinity):
2393
+ if isinstance(i.upper(), AnInfinity):
2394
+ return ZZ.zero()
2395
+ else:
2396
+ return i.upper() - 1
2397
+ if isinstance(i.upper(), AnInfinity):
2398
+ return i.lower() + 1
2399
+ if i.lower_closed():
2400
+ return i.lower()
2401
+ if i.upper_closed():
2402
+ return i.upper()
2403
+ return (i.lower() + i.upper()) / ZZ(2)
2404
+
2405
+ def is_open(self):
2406
+ """
2407
+ Return whether ``self`` is an open set.
2408
+
2409
+ EXAMPLES::
2410
+
2411
+ sage: RealSet().is_open()
2412
+ True
2413
+ sage: RealSet.point(1).is_open()
2414
+ False
2415
+ sage: RealSet((1, 2)).is_open()
2416
+ True
2417
+ sage: RealSet([1, 2], (3, 4)).is_open()
2418
+ False
2419
+ sage: RealSet(-oo, +oo).is_open()
2420
+ True
2421
+ """
2422
+ return all(not i.lower_closed()
2423
+ and not i.upper_closed()
2424
+ for i in self._intervals)
2425
+
2426
+ def is_closed(self):
2427
+ """
2428
+ Return whether ``self`` is a closed set.
2429
+
2430
+ EXAMPLES::
2431
+
2432
+ sage: RealSet().is_closed()
2433
+ True
2434
+ sage: RealSet.point(1).is_closed()
2435
+ True
2436
+ sage: RealSet([1, 2]).is_closed()
2437
+ True
2438
+ sage: RealSet([1, 2], (3, 4)).is_closed()
2439
+ False
2440
+ sage: RealSet(-oo, +oo).is_closed()
2441
+ True
2442
+ """
2443
+ return all((i.lower_closed() or i.lower() is minus_infinity)
2444
+ and (i.upper_closed() or i.upper() is infinity)
2445
+ for i in self._intervals)
2446
+
2447
+ def closure(self):
2448
+ """
2449
+ Return the topological closure of ``self`` as a new :class:`RealSet`.
2450
+
2451
+ EXAMPLES::
2452
+
2453
+ sage: RealSet(-oo, oo).closure()
2454
+ (-oo, +oo)
2455
+ sage: RealSet((1, 2), (2, 3)).closure()
2456
+ [1, 3]
2457
+ sage: RealSet().closure()
2458
+ {}
2459
+ """
2460
+ return RealSet(*[i.closure() for i in self._intervals])
2461
+
2462
+ def interior(self):
2463
+ """
2464
+ Return the topological interior of ``self`` as a new :class:`RealSet`.
2465
+
2466
+ EXAMPLES::
2467
+
2468
+ sage: RealSet(-oo, oo).interior()
2469
+ (-oo, +oo)
2470
+ sage: RealSet().interior()
2471
+ {}
2472
+ sage: RealSet.point(2).interior()
2473
+ {}
2474
+ sage: RealSet([1, 2], (3, 4)).interior()
2475
+ (1, 2) ∪ (3, 4)
2476
+ """
2477
+ return RealSet(*[i.interior() for i in self._intervals])
2478
+
2479
+ def boundary(self):
2480
+ """
2481
+ Return the topological boundary of ``self`` as a new :class:`RealSet`.
2482
+
2483
+ EXAMPLES::
2484
+
2485
+ sage: RealSet(-oo, oo).boundary()
2486
+ {}
2487
+ sage: RealSet().boundary()
2488
+ {}
2489
+ sage: RealSet.point(2).boundary()
2490
+ {2}
2491
+ sage: RealSet([1, 2], (3, 4)).boundary()
2492
+ {1} ∪ {2} ∪ {3} ∪ {4}
2493
+ sage: RealSet((1, 2), (2, 3)).boundary()
2494
+ {1} ∪ {2} ∪ {3}
2495
+ """
2496
+ return RealSet(*[RealSet.point(x) for i in self._intervals for x in i.boundary_points()])
2497
+
2498
+ @staticmethod
2499
+ def convex_hull(*real_set_collection):
2500
+ """
2501
+ Return the convex hull of real sets.
2502
+
2503
+ INPUT:
2504
+
2505
+ - ``*real_set_collection`` -- list/tuple/iterable of :class:`RealSet`
2506
+ or data that defines one
2507
+
2508
+ OUTPUT: the convex hull as a new :class:`RealSet`
2509
+
2510
+ EXAMPLES::
2511
+
2512
+ sage: s1 = RealSet(0,2) + RealSet.unbounded_above_closed(10); s1 # unbounded set
2513
+ (0, 2) ∪ [10, +oo)
2514
+ sage: s2 = RealSet(1,3) + RealSet.unbounded_below_closed(-10); s2
2515
+ (-oo, -10] ∪ (1, 3)
2516
+ sage: s3 = RealSet((0,2), RealSet.point(8)); s3
2517
+ (0, 2) ∪ {8}
2518
+ sage: s4 = RealSet(); s4 # empty set
2519
+ {}
2520
+ sage: RealSet.convex_hull(s1)
2521
+ (0, +oo)
2522
+ sage: RealSet.convex_hull(s2)
2523
+ (-oo, 3)
2524
+ sage: RealSet.convex_hull(s3)
2525
+ (0, 8]
2526
+ sage: RealSet.convex_hull(s4)
2527
+ {}
2528
+ sage: RealSet.convex_hull(s1, s2)
2529
+ (-oo, +oo)
2530
+ sage: RealSet.convex_hull(s2, s3)
2531
+ (-oo, 8]
2532
+ sage: RealSet.convex_hull(s2, s3, s4)
2533
+ (-oo, 8]
2534
+ """
2535
+ lower_scan = ((infinity, 0), 1)
2536
+ upper_scan = ((minus_infinity, 1), -1)
2537
+ for real_set in real_set_collection:
2538
+ s = RealSet(real_set)
2539
+ if s.n_components() > 0:
2540
+ lower_s = s[0]._scan_lower()
2541
+ lower_scan = min(lower_s, lower_scan)
2542
+ upper_s = s[-1]._scan_upper()
2543
+ upper_scan = max(upper_s, upper_scan)
2544
+ if lower_scan < upper_scan:
2545
+ lower, lower_closed = lower_scan[0][0], lower_scan[0][1] == 0
2546
+ upper, upper_closed = upper_scan[0][0], upper_scan[0][1] > 0
2547
+ return RealSet(InternalRealInterval(lower, lower_closed, upper, upper_closed))
2548
+ else:
2549
+ return RealSet()
2550
+
2551
+ def is_connected(self):
2552
+ """
2553
+ Return whether ``self`` is a connected set.
2554
+
2555
+ OUTPUT: boolean
2556
+
2557
+ EXAMPLES::
2558
+
2559
+ sage: s1 = RealSet((1, 2), (2, 4)); s1
2560
+ (1, 2) ∪ (2, 4)
2561
+ sage: s1.is_connected()
2562
+ False
2563
+ sage: s2 = RealSet((1, 2), (2, 4), RealSet.point(2)); s2
2564
+ (1, 4)
2565
+ sage: s2.is_connected()
2566
+ True
2567
+ sage: s3 = RealSet(1,3) + RealSet.unbounded_below_closed(-10); s3
2568
+ (-oo, -10] ∪ (1, 3)
2569
+ sage: s3.is_connected()
2570
+ False
2571
+ sage: RealSet(x != 0).is_connected() # needs sage.symbolic
2572
+ False
2573
+ sage: RealSet(-oo, oo).is_connected()
2574
+ True
2575
+ sage: RealSet().is_connected()
2576
+ False
2577
+ """
2578
+ return self.n_components() == 1
2579
+
2580
+ def is_disjoint(self, *other):
2581
+ """
2582
+ Test whether the two sets are disjoint.
2583
+
2584
+ INPUT:
2585
+
2586
+ - ``other`` -- a :class:`RealSet` or data defining one
2587
+
2588
+ OUTPUT: boolean
2589
+
2590
+ .. SEEALSO:: :meth:`are_pairwise_disjoint`
2591
+
2592
+ EXAMPLES::
2593
+
2594
+ sage: s = RealSet((0, 1), (2, 3)); s
2595
+ (0, 1) ∪ (2, 3)
2596
+ sage: s.is_disjoint(RealSet([1, 2]))
2597
+ True
2598
+ sage: s.is_disjoint([3/2, 5/2])
2599
+ False
2600
+ sage: s.is_disjoint(RealSet())
2601
+ True
2602
+ sage: s.is_disjoint(RealSet().real_line())
2603
+ False
2604
+ """
2605
+ other = RealSet(*other)
2606
+ return self.are_pairwise_disjoint(self, other)
2607
+
2608
+ is_disjoint_from = deprecated_function_alias(31927, is_disjoint)
2609
+
2610
+ @staticmethod
2611
+ def are_pairwise_disjoint(*real_set_collection):
2612
+ """
2613
+ Test whether the real sets are pairwise disjoint.
2614
+
2615
+ INPUT:
2616
+
2617
+ - ``*real_set_collection`` -- list/tuple/iterable of :class:`RealSet`
2618
+ or data that defines one
2619
+
2620
+ OUTPUT: boolean
2621
+
2622
+ .. SEEALSO:: :meth:`is_disjoint`
2623
+
2624
+ EXAMPLES::
2625
+
2626
+ sage: s1 = RealSet((0, 1), (2, 3))
2627
+ sage: s2 = RealSet((1, 2))
2628
+ sage: s3 = RealSet.point(3)
2629
+ sage: RealSet.are_pairwise_disjoint(s1, s2, s3)
2630
+ True
2631
+ sage: RealSet.are_pairwise_disjoint(s1, s2, s3, [10,10])
2632
+ True
2633
+ sage: RealSet.are_pairwise_disjoint(s1, s2, s3, [-1, 1/2])
2634
+ False
2635
+ """
2636
+ scan = merge(*[RealSet(real_set)._scan() for real_set in real_set_collection])
2637
+ overlap_generator = RealSet._scan_to_intervals(scan, lambda i: i > 1)
2638
+ return next(overlap_generator, None) is None
2639
+
2640
+ def _sage_input_(self, sib, coerced):
2641
+ """
2642
+ Produce an expression which will reproduce this value when evaluated.
2643
+
2644
+ TESTS::
2645
+
2646
+ sage: sage_input(RealSet())
2647
+ RealSet()
2648
+ sage: sage_input(RealSet.open(-oo, +oo))
2649
+ RealSet(-oo, oo)
2650
+ sage: sage_input(RealSet.point(77))
2651
+ RealSet.point(77)
2652
+ sage: sage_input(RealSet.closed_open(0, +oo))
2653
+ RealSet.closed_open(0, oo)
2654
+ sage: sage_input(RealSet.open_closed(-oo, 0))
2655
+ RealSet.open_closed(-oo, 0)
2656
+ sage: sage_input(RealSet.open_closed(-1, 0))
2657
+ RealSet.open_closed(-1, 0)
2658
+ sage: sage_input(RealSet.closed_open(-1, 0))
2659
+ RealSet.closed_open(-1, 0)
2660
+ sage: sage_input(RealSet.closed(0, 1))
2661
+ RealSet.closed(0, 1)
2662
+ sage: sage_input(RealSet.open(0, 1))
2663
+ RealSet.open(0, 1)
2664
+ sage: sage_input(RealSet.open(0, 1) + RealSet.open(1, 2))
2665
+ RealSet.open(0, 1) + RealSet.open(1, 2)
2666
+ """
2667
+
2668
+ def interval_input(i):
2669
+ lower, upper = i.lower(), i.upper()
2670
+ if i.is_point():
2671
+ return sib.name('RealSet.point')(lower)
2672
+ elif lower == minus_infinity and upper == infinity:
2673
+ return sib.name('RealSet')(sib(minus_infinity), sib(infinity))
2674
+ else:
2675
+ if i.lower_closed():
2676
+ if i.upper_closed():
2677
+ t = 'RealSet.closed'
2678
+ else:
2679
+ t = 'RealSet.closed_open'
2680
+ else:
2681
+ if i.upper_closed():
2682
+ t = 'RealSet.open_closed'
2683
+ else:
2684
+ t = 'RealSet.open'
2685
+ return sib.name(t)(sib(lower), sib(upper))
2686
+
2687
+ if self.is_empty():
2688
+ return sib.name('RealSet')()
2689
+ else:
2690
+ return sib.sum(interval_input(i) for i in self)
2691
+
2692
+ def __mul__(self, right):
2693
+ r"""
2694
+ Scale a real set by a scalar on the left or right.
2695
+
2696
+ EXAMPLES::
2697
+
2698
+ sage: A = RealSet([0, 1/2], (2, infinity)); A
2699
+ [0, 1/2] ∪ (2, +oo)
2700
+ sage: 2 * A
2701
+ [0, 1] ∪ (4, +oo)
2702
+ sage: A * 100
2703
+ [0, 50] ∪ (200, +oo)
2704
+ sage: 1.5 * A
2705
+ [0.000000000000000, 0.750000000000000] ∪ (3.00000000000000, +oo)
2706
+ sage: (-2) * A
2707
+ (-oo, -4) ∪ [-1, 0]
2708
+ """
2709
+ if not isinstance(right, RealSet):
2710
+ return RealSet(*[e * right for e in self])
2711
+ elif not isinstance(self, RealSet):
2712
+ return RealSet(*[self * e for e in right])
2713
+ else:
2714
+ return NotImplemented
2715
+
2716
+ def __rmul__(self, other):
2717
+ r"""
2718
+ Scale a real set by a scalar on the left.
2719
+
2720
+ TESTS::
2721
+
2722
+ sage: A = RealSet([0, 1/2], RealSet.unbounded_above_closed(2)); A
2723
+ [0, 1/2] ∪ [2, +oo)
2724
+ sage: pi * A # needs sage.symbolic
2725
+ [0, 1/2*pi] ∪ [2*pi, +oo)
2726
+ """
2727
+ return self * other
2728
+
2729
+ def _sympy_(self):
2730
+ r"""
2731
+ Return the SymPy set corresponding to ``self``.
2732
+
2733
+ EXAMPLES::
2734
+
2735
+ sage: # needs sympy
2736
+ sage: RealSet()._sympy_()
2737
+ EmptySet
2738
+ sage: RealSet.point(5)._sympy_() # random - this format is sympy >= 1.9
2739
+ {5}
2740
+ sage: (RealSet.point(1).union(RealSet.point(2)))._sympy_() # random
2741
+ {1, 2}
2742
+ sage: (RealSet(1, 2).union(RealSet.closed(3, 4)))._sympy_()
2743
+ Union(Interval.open(1, 2), Interval(3, 4))
2744
+ sage: RealSet(-oo, oo)._sympy_()
2745
+ Reals
2746
+
2747
+ Infinities are not elements::
2748
+
2749
+ sage: import sympy # needs sympy
2750
+ sage: RealSet(-oo, oo)._sympy_().contains(sympy.oo) # needs sympy
2751
+ False
2752
+ """
2753
+ from sympy import Reals, Union
2754
+ from sage.interfaces.sympy import sympy_init
2755
+ sympy_init()
2756
+ if self.is_universe():
2757
+ return Reals
2758
+ else:
2759
+ return Union(*[interval._sympy_()
2760
+ for interval in self._intervals])