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.
- passagemath_categories-10.6.32.dist-info/METADATA +156 -0
- passagemath_categories-10.6.32.dist-info/RECORD +719 -0
- passagemath_categories-10.6.32.dist-info/WHEEL +5 -0
- passagemath_categories-10.6.32.dist-info/top_level.txt +2 -0
- passagemath_categories.libs/libgcc_s-2d945d6c.so.1 +0 -0
- passagemath_categories.libs/libgmp-28992bcb.so.10.5.0 +0 -0
- passagemath_categories.libs/libstdc++-85f2cd6d.so.6.0.33 +0 -0
- sage/all__sagemath_categories.py +28 -0
- sage/arith/all.py +38 -0
- sage/arith/constants.pxd +27 -0
- sage/arith/functions.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/arith/functions.pxd +4 -0
- sage/arith/functions.pyx +221 -0
- sage/arith/misc.py +6552 -0
- sage/arith/multi_modular.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/arith/multi_modular.pxd +39 -0
- sage/arith/multi_modular.pyx +994 -0
- sage/arith/rational_reconstruction.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/arith/rational_reconstruction.pxd +4 -0
- sage/arith/rational_reconstruction.pyx +115 -0
- sage/arith/srange.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/arith/srange.pyx +571 -0
- sage/calculus/all__sagemath_categories.py +2 -0
- sage/calculus/functional.py +481 -0
- sage/calculus/functions.py +151 -0
- sage/categories/additive_groups.py +73 -0
- sage/categories/additive_magmas.py +1044 -0
- sage/categories/additive_monoids.py +114 -0
- sage/categories/additive_semigroups.py +184 -0
- sage/categories/affine_weyl_groups.py +238 -0
- sage/categories/algebra_ideals.py +95 -0
- sage/categories/algebra_modules.py +96 -0
- sage/categories/algebras.py +349 -0
- sage/categories/algebras_with_basis.py +377 -0
- sage/categories/all.py +160 -0
- sage/categories/aperiodic_semigroups.py +29 -0
- sage/categories/associative_algebras.py +47 -0
- sage/categories/bialgebras.py +101 -0
- sage/categories/bialgebras_with_basis.py +414 -0
- sage/categories/bimodules.py +206 -0
- sage/categories/chain_complexes.py +268 -0
- sage/categories/classical_crystals.py +480 -0
- sage/categories/coalgebras.py +405 -0
- sage/categories/coalgebras_with_basis.py +232 -0
- sage/categories/coercion_methods.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/categories/coercion_methods.pyx +52 -0
- sage/categories/commutative_additive_groups.py +104 -0
- sage/categories/commutative_additive_monoids.py +45 -0
- sage/categories/commutative_additive_semigroups.py +48 -0
- sage/categories/commutative_algebra_ideals.py +87 -0
- sage/categories/commutative_algebras.py +94 -0
- sage/categories/commutative_ring_ideals.py +58 -0
- sage/categories/commutative_rings.py +736 -0
- sage/categories/complete_discrete_valuation.py +293 -0
- sage/categories/complex_reflection_groups.py +145 -0
- sage/categories/complex_reflection_or_generalized_coxeter_groups.py +1249 -0
- sage/categories/coxeter_group_algebras.py +186 -0
- sage/categories/coxeter_groups.py +3402 -0
- sage/categories/crystals.py +2628 -0
- sage/categories/cw_complexes.py +216 -0
- sage/categories/dedekind_domains.py +137 -0
- sage/categories/discrete_valuation.py +325 -0
- sage/categories/distributive_magmas_and_additive_magmas.py +100 -0
- sage/categories/division_rings.py +114 -0
- sage/categories/domains.py +95 -0
- sage/categories/drinfeld_modules.py +789 -0
- sage/categories/dual.py +42 -0
- sage/categories/enumerated_sets.py +1146 -0
- sage/categories/euclidean_domains.py +271 -0
- sage/categories/examples/algebras_with_basis.py +102 -0
- sage/categories/examples/all.py +1 -0
- sage/categories/examples/commutative_additive_monoids.py +130 -0
- sage/categories/examples/commutative_additive_semigroups.py +199 -0
- sage/categories/examples/coxeter_groups.py +8 -0
- sage/categories/examples/crystals.py +236 -0
- sage/categories/examples/cw_complexes.py +163 -0
- sage/categories/examples/facade_sets.py +187 -0
- sage/categories/examples/filtered_algebras_with_basis.py +204 -0
- sage/categories/examples/filtered_modules_with_basis.py +154 -0
- sage/categories/examples/finite_coxeter_groups.py +252 -0
- sage/categories/examples/finite_dimensional_algebras_with_basis.py +148 -0
- sage/categories/examples/finite_dimensional_lie_algebras_with_basis.py +495 -0
- sage/categories/examples/finite_enumerated_sets.py +208 -0
- sage/categories/examples/finite_monoids.py +150 -0
- sage/categories/examples/finite_semigroups.py +190 -0
- sage/categories/examples/finite_weyl_groups.py +191 -0
- sage/categories/examples/graded_connected_hopf_algebras_with_basis.py +152 -0
- sage/categories/examples/graded_modules_with_basis.py +168 -0
- sage/categories/examples/graphs.py +122 -0
- sage/categories/examples/hopf_algebras_with_basis.py +145 -0
- sage/categories/examples/infinite_enumerated_sets.py +190 -0
- sage/categories/examples/lie_algebras.py +352 -0
- sage/categories/examples/lie_algebras_with_basis.py +196 -0
- sage/categories/examples/magmas.py +162 -0
- sage/categories/examples/manifolds.py +94 -0
- sage/categories/examples/monoids.py +144 -0
- sage/categories/examples/posets.py +178 -0
- sage/categories/examples/semigroups.py +580 -0
- sage/categories/examples/semigroups_cython.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/categories/examples/semigroups_cython.pyx +221 -0
- sage/categories/examples/semirings.py +249 -0
- sage/categories/examples/sets_cat.py +706 -0
- sage/categories/examples/sets_with_grading.py +101 -0
- sage/categories/examples/with_realizations.py +542 -0
- sage/categories/fields.py +991 -0
- sage/categories/filtered_algebras.py +63 -0
- sage/categories/filtered_algebras_with_basis.py +548 -0
- sage/categories/filtered_hopf_algebras_with_basis.py +138 -0
- sage/categories/filtered_modules.py +210 -0
- sage/categories/filtered_modules_with_basis.py +1209 -0
- sage/categories/finite_complex_reflection_groups.py +1506 -0
- sage/categories/finite_coxeter_groups.py +1138 -0
- sage/categories/finite_crystals.py +103 -0
- sage/categories/finite_dimensional_algebras_with_basis.py +1860 -0
- sage/categories/finite_dimensional_bialgebras_with_basis.py +33 -0
- sage/categories/finite_dimensional_coalgebras_with_basis.py +33 -0
- sage/categories/finite_dimensional_graded_lie_algebras_with_basis.py +231 -0
- sage/categories/finite_dimensional_hopf_algebras_with_basis.py +38 -0
- sage/categories/finite_dimensional_lie_algebras_with_basis.py +2774 -0
- sage/categories/finite_dimensional_modules_with_basis.py +1407 -0
- sage/categories/finite_dimensional_nilpotent_lie_algebras_with_basis.py +167 -0
- sage/categories/finite_dimensional_semisimple_algebras_with_basis.py +270 -0
- sage/categories/finite_enumerated_sets.py +769 -0
- sage/categories/finite_fields.py +252 -0
- sage/categories/finite_groups.py +256 -0
- sage/categories/finite_lattice_posets.py +242 -0
- sage/categories/finite_monoids.py +316 -0
- sage/categories/finite_permutation_groups.py +339 -0
- sage/categories/finite_posets.py +1994 -0
- sage/categories/finite_semigroups.py +136 -0
- sage/categories/finite_sets.py +93 -0
- sage/categories/finite_weyl_groups.py +39 -0
- sage/categories/finitely_generated_lambda_bracket_algebras.py +112 -0
- sage/categories/finitely_generated_lie_conformal_algebras.py +114 -0
- sage/categories/finitely_generated_magmas.py +57 -0
- sage/categories/finitely_generated_semigroups.py +214 -0
- sage/categories/function_fields.py +76 -0
- sage/categories/g_sets.py +77 -0
- sage/categories/gcd_domains.py +65 -0
- sage/categories/generalized_coxeter_groups.py +94 -0
- sage/categories/graded_algebras.py +85 -0
- sage/categories/graded_algebras_with_basis.py +258 -0
- sage/categories/graded_bialgebras.py +32 -0
- sage/categories/graded_bialgebras_with_basis.py +32 -0
- sage/categories/graded_coalgebras.py +65 -0
- sage/categories/graded_coalgebras_with_basis.py +51 -0
- sage/categories/graded_hopf_algebras.py +41 -0
- sage/categories/graded_hopf_algebras_with_basis.py +169 -0
- sage/categories/graded_lie_algebras.py +91 -0
- sage/categories/graded_lie_algebras_with_basis.py +44 -0
- sage/categories/graded_lie_conformal_algebras.py +74 -0
- sage/categories/graded_modules.py +133 -0
- sage/categories/graded_modules_with_basis.py +329 -0
- sage/categories/graphs.py +138 -0
- sage/categories/group_algebras.py +430 -0
- sage/categories/groupoid.py +94 -0
- sage/categories/groups.py +667 -0
- sage/categories/h_trivial_semigroups.py +64 -0
- sage/categories/hecke_modules.py +185 -0
- sage/categories/highest_weight_crystals.py +980 -0
- sage/categories/hopf_algebras.py +219 -0
- sage/categories/hopf_algebras_with_basis.py +309 -0
- sage/categories/infinite_enumerated_sets.py +115 -0
- sage/categories/integral_domains.py +203 -0
- sage/categories/j_trivial_semigroups.py +29 -0
- sage/categories/kac_moody_algebras.py +82 -0
- sage/categories/kahler_algebras.py +203 -0
- sage/categories/l_trivial_semigroups.py +63 -0
- sage/categories/lambda_bracket_algebras.py +280 -0
- sage/categories/lambda_bracket_algebras_with_basis.py +107 -0
- sage/categories/lattice_posets.py +89 -0
- sage/categories/left_modules.py +49 -0
- sage/categories/lie_algebras.py +1070 -0
- sage/categories/lie_algebras_with_basis.py +261 -0
- sage/categories/lie_conformal_algebras.py +350 -0
- sage/categories/lie_conformal_algebras_with_basis.py +147 -0
- sage/categories/lie_groups.py +73 -0
- sage/categories/loop_crystals.py +1290 -0
- sage/categories/magmas.py +1189 -0
- sage/categories/magmas_and_additive_magmas.py +149 -0
- sage/categories/magmatic_algebras.py +365 -0
- sage/categories/manifolds.py +352 -0
- sage/categories/matrix_algebras.py +40 -0
- sage/categories/metric_spaces.py +387 -0
- sage/categories/modular_abelian_varieties.py +78 -0
- sage/categories/modules.py +989 -0
- sage/categories/modules_with_basis.py +2794 -0
- sage/categories/monoid_algebras.py +38 -0
- sage/categories/monoids.py +739 -0
- sage/categories/noetherian_rings.py +87 -0
- sage/categories/number_fields.py +242 -0
- sage/categories/ore_modules.py +189 -0
- sage/categories/partially_ordered_monoids.py +49 -0
- sage/categories/permutation_groups.py +63 -0
- sage/categories/pointed_sets.py +42 -0
- sage/categories/polyhedra.py +74 -0
- sage/categories/poor_man_map.py +270 -0
- sage/categories/posets.py +722 -0
- sage/categories/principal_ideal_domains.py +270 -0
- sage/categories/quantum_group_representations.py +543 -0
- sage/categories/quotient_fields.py +728 -0
- sage/categories/r_trivial_semigroups.py +45 -0
- sage/categories/regular_crystals.py +898 -0
- sage/categories/regular_supercrystals.py +170 -0
- sage/categories/right_modules.py +49 -0
- sage/categories/ring_ideals.py +74 -0
- sage/categories/rings.py +1904 -0
- sage/categories/rngs.py +175 -0
- sage/categories/schemes.py +393 -0
- sage/categories/semigroups.py +1060 -0
- sage/categories/semirings.py +71 -0
- sage/categories/semisimple_algebras.py +114 -0
- sage/categories/sets_with_grading.py +235 -0
- sage/categories/shephard_groups.py +43 -0
- sage/categories/signed_tensor.py +120 -0
- sage/categories/simplicial_complexes.py +134 -0
- sage/categories/simplicial_sets.py +1206 -0
- sage/categories/super_algebras.py +149 -0
- sage/categories/super_algebras_with_basis.py +144 -0
- sage/categories/super_hopf_algebras_with_basis.py +126 -0
- sage/categories/super_lie_conformal_algebras.py +193 -0
- sage/categories/super_modules.py +229 -0
- sage/categories/super_modules_with_basis.py +193 -0
- sage/categories/supercommutative_algebras.py +99 -0
- sage/categories/supercrystals.py +406 -0
- sage/categories/tensor.py +110 -0
- sage/categories/topological_spaces.py +170 -0
- sage/categories/triangular_kac_moody_algebras.py +439 -0
- sage/categories/tutorial.py +58 -0
- sage/categories/unique_factorization_domains.py +318 -0
- sage/categories/unital_algebras.py +426 -0
- sage/categories/vector_bundles.py +159 -0
- sage/categories/vector_spaces.py +357 -0
- sage/categories/weyl_groups.py +853 -0
- sage/combinat/all__sagemath_categories.py +34 -0
- sage/combinat/backtrack.py +180 -0
- sage/combinat/combinat.py +2269 -0
- sage/combinat/combinat_cython.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/combinat_cython.pxd +6 -0
- sage/combinat/combinat_cython.pyx +390 -0
- sage/combinat/combination.py +796 -0
- sage/combinat/combinatorial_map.py +416 -0
- sage/combinat/composition.py +2192 -0
- sage/combinat/dlx.py +510 -0
- sage/combinat/integer_lists/__init__.py +7 -0
- sage/combinat/integer_lists/base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/integer_lists/base.pxd +16 -0
- sage/combinat/integer_lists/base.pyx +713 -0
- sage/combinat/integer_lists/invlex.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/integer_lists/invlex.pxd +4 -0
- sage/combinat/integer_lists/invlex.pyx +1650 -0
- sage/combinat/integer_lists/lists.py +328 -0
- sage/combinat/integer_lists/nn.py +48 -0
- sage/combinat/integer_vector.py +1818 -0
- sage/combinat/integer_vector_weighted.py +413 -0
- sage/combinat/matrices/all__sagemath_categories.py +5 -0
- sage/combinat/matrices/dancing_links.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/matrices/dancing_links.pyx +1159 -0
- sage/combinat/matrices/dancing_links_c.h +380 -0
- sage/combinat/matrices/dlxcpp.py +136 -0
- sage/combinat/partition.py +10070 -0
- sage/combinat/partitions.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/partitions.pyx +743 -0
- sage/combinat/permutation.py +10168 -0
- sage/combinat/permutation_cython.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/permutation_cython.pxd +11 -0
- sage/combinat/permutation_cython.pyx +407 -0
- sage/combinat/q_analogues.py +1090 -0
- sage/combinat/ranker.py +268 -0
- sage/combinat/subset.py +1561 -0
- sage/combinat/subsets_hereditary.py +202 -0
- sage/combinat/subsets_pairwise.py +184 -0
- sage/combinat/tools.py +63 -0
- sage/combinat/tuple.py +348 -0
- sage/data_structures/all.py +2 -0
- sage/data_structures/all__sagemath_categories.py +2 -0
- sage/data_structures/binary_matrix.pxd +138 -0
- sage/data_structures/binary_search.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/binary_search.pxd +3 -0
- sage/data_structures/binary_search.pyx +66 -0
- sage/data_structures/bitset.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/bitset.pxd +40 -0
- sage/data_structures/bitset.pyx +2385 -0
- sage/data_structures/bitset_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/bitset_base.pxd +926 -0
- sage/data_structures/bitset_base.pyx +117 -0
- sage/data_structures/bitset_intrinsics.h +487 -0
- sage/data_structures/blas_dict.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/blas_dict.pxd +12 -0
- sage/data_structures/blas_dict.pyx +469 -0
- sage/data_structures/list_of_pairs.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/list_of_pairs.pxd +16 -0
- sage/data_structures/list_of_pairs.pyx +122 -0
- sage/data_structures/mutable_poset.py +3312 -0
- sage/data_structures/pairing_heap.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/pairing_heap.h +346 -0
- sage/data_structures/pairing_heap.pxd +88 -0
- sage/data_structures/pairing_heap.pyx +1464 -0
- sage/data_structures/sparse_bitset.pxd +62 -0
- sage/data_structures/stream.py +5070 -0
- sage/databases/all__sagemath_categories.py +7 -0
- sage/databases/sql_db.py +2236 -0
- sage/ext/all__sagemath_categories.py +3 -0
- sage/ext/fast_callable.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/ext/fast_callable.pxd +4 -0
- sage/ext/fast_callable.pyx +2746 -0
- sage/ext/fast_eval.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/ext/fast_eval.pxd +1 -0
- sage/ext/fast_eval.pyx +102 -0
- sage/ext/interpreters/__init__.py +1 -0
- sage/ext/interpreters/all__sagemath_categories.py +2 -0
- sage/ext/interpreters/wrapper_el.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_el.pxd +18 -0
- sage/ext/interpreters/wrapper_el.pyx +148 -0
- sage/ext/interpreters/wrapper_py.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_py.pxd +17 -0
- sage/ext/interpreters/wrapper_py.pyx +133 -0
- sage/functions/airy.py +937 -0
- sage/functions/all.py +97 -0
- sage/functions/bessel.py +2102 -0
- sage/functions/error.py +784 -0
- sage/functions/exp_integral.py +1529 -0
- sage/functions/gamma.py +1087 -0
- sage/functions/generalized.py +672 -0
- sage/functions/hyperbolic.py +747 -0
- sage/functions/hypergeometric.py +1156 -0
- sage/functions/jacobi.py +1705 -0
- sage/functions/log.py +1402 -0
- sage/functions/min_max.py +338 -0
- sage/functions/orthogonal_polys.py +3106 -0
- sage/functions/other.py +2303 -0
- sage/functions/piecewise.py +1505 -0
- sage/functions/prime_pi.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/functions/prime_pi.pyx +262 -0
- sage/functions/special.py +1212 -0
- sage/functions/spike_function.py +278 -0
- sage/functions/transcendental.py +690 -0
- sage/functions/trig.py +1062 -0
- sage/functions/wigner.py +726 -0
- sage/geometry/abc.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/geometry/abc.pyx +82 -0
- sage/geometry/all__sagemath_categories.py +1 -0
- sage/groups/all__sagemath_categories.py +11 -0
- sage/groups/generic.py +1733 -0
- sage/groups/groups_catalog.py +113 -0
- sage/groups/perm_gps/all__sagemath_categories.py +1 -0
- sage/groups/perm_gps/partn_ref/all.py +1 -0
- sage/groups/perm_gps/partn_ref/all__sagemath_categories.py +1 -0
- sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pxd +52 -0
- sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx +906 -0
- sage/groups/perm_gps/partn_ref/canonical_augmentation.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/canonical_augmentation.pxd +85 -0
- sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx +534 -0
- sage/groups/perm_gps/partn_ref/data_structures.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/data_structures.pxd +576 -0
- sage/groups/perm_gps/partn_ref/data_structures.pyx +1792 -0
- sage/groups/perm_gps/partn_ref/double_coset.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/double_coset.pxd +45 -0
- sage/groups/perm_gps/partn_ref/double_coset.pyx +739 -0
- sage/groups/perm_gps/partn_ref/refinement_lists.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_lists.pxd +18 -0
- sage/groups/perm_gps/partn_ref/refinement_lists.pyx +82 -0
- sage/groups/perm_gps/partn_ref/refinement_python.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_python.pxd +16 -0
- sage/groups/perm_gps/partn_ref/refinement_python.pyx +564 -0
- sage/groups/perm_gps/partn_ref/refinement_sets.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_sets.pxd +60 -0
- sage/groups/perm_gps/partn_ref/refinement_sets.pyx +858 -0
- sage/interfaces/abc.py +140 -0
- sage/interfaces/all.py +58 -0
- sage/interfaces/all__sagemath_categories.py +1 -0
- sage/interfaces/expect.py +1643 -0
- sage/interfaces/interface.py +1682 -0
- sage/interfaces/process.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/interfaces/process.pxd +5 -0
- sage/interfaces/process.pyx +288 -0
- sage/interfaces/quit.py +167 -0
- sage/interfaces/sage0.py +604 -0
- sage/interfaces/sagespawn.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/interfaces/sagespawn.pyx +308 -0
- sage/interfaces/tab_completion.py +101 -0
- sage/misc/all__sagemath_categories.py +78 -0
- sage/misc/allocator.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/allocator.pxd +6 -0
- sage/misc/allocator.pyx +47 -0
- sage/misc/binary_tree.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/binary_tree.pxd +29 -0
- sage/misc/binary_tree.pyx +537 -0
- sage/misc/callable_dict.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/callable_dict.pyx +89 -0
- sage/misc/citation.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/citation.pyx +159 -0
- sage/misc/converting_dict.py +293 -0
- sage/misc/defaults.py +129 -0
- sage/misc/derivative.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/derivative.pyx +223 -0
- sage/misc/functional.py +2005 -0
- sage/misc/html.py +589 -0
- sage/misc/latex.py +2673 -0
- sage/misc/latex_macros.py +236 -0
- sage/misc/latex_standalone.py +1833 -0
- sage/misc/map_threaded.py +38 -0
- sage/misc/mathml.py +76 -0
- sage/misc/method_decorator.py +88 -0
- sage/misc/mrange.py +755 -0
- sage/misc/multireplace.py +41 -0
- sage/misc/object_multiplexer.py +92 -0
- sage/misc/parser.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/parser.pyx +1107 -0
- sage/misc/random_testing.py +264 -0
- sage/misc/rest_index_of_methods.py +377 -0
- sage/misc/search.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/search.pxd +2 -0
- sage/misc/search.pyx +68 -0
- sage/misc/stopgap.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/stopgap.pyx +95 -0
- sage/misc/table.py +853 -0
- sage/monoids/all__sagemath_categories.py +1 -0
- sage/monoids/indexed_free_monoid.py +1071 -0
- sage/monoids/monoid.py +82 -0
- sage/numerical/all__sagemath_categories.py +1 -0
- sage/numerical/backends/all__sagemath_categories.py +1 -0
- sage/numerical/backends/generic_backend.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/numerical/backends/generic_backend.pxd +61 -0
- sage/numerical/backends/generic_backend.pyx +1893 -0
- sage/numerical/backends/generic_sdp_backend.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/numerical/backends/generic_sdp_backend.pxd +38 -0
- sage/numerical/backends/generic_sdp_backend.pyx +755 -0
- sage/parallel/all.py +6 -0
- sage/parallel/decorate.py +575 -0
- sage/parallel/map_reduce.py +1997 -0
- sage/parallel/multiprocessing_sage.py +76 -0
- sage/parallel/ncpus.py +35 -0
- sage/parallel/parallelism.py +364 -0
- sage/parallel/reference.py +47 -0
- sage/parallel/use_fork.py +333 -0
- sage/rings/abc.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/abc.pxd +31 -0
- sage/rings/abc.pyx +526 -0
- sage/rings/algebraic_closure_finite_field.py +1154 -0
- sage/rings/all__sagemath_categories.py +91 -0
- sage/rings/big_oh.py +227 -0
- sage/rings/continued_fraction.py +2754 -0
- sage/rings/continued_fraction_gosper.py +220 -0
- sage/rings/factorint.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/factorint.pyx +295 -0
- sage/rings/fast_arith.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/fast_arith.pxd +21 -0
- sage/rings/fast_arith.pyx +535 -0
- sage/rings/finite_rings/all__sagemath_categories.py +9 -0
- sage/rings/finite_rings/conway_polynomials.py +542 -0
- sage/rings/finite_rings/element_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/element_base.pxd +12 -0
- sage/rings/finite_rings/element_base.pyx +1176 -0
- sage/rings/finite_rings/finite_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/finite_field_base.pxd +7 -0
- sage/rings/finite_rings/finite_field_base.pyx +2171 -0
- sage/rings/finite_rings/finite_field_constructor.py +827 -0
- sage/rings/finite_rings/finite_field_prime_modn.py +372 -0
- sage/rings/finite_rings/galois_group.py +154 -0
- sage/rings/finite_rings/hom_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/hom_finite_field.pxd +23 -0
- sage/rings/finite_rings/hom_finite_field.pyx +856 -0
- sage/rings/finite_rings/hom_prime_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/hom_prime_finite_field.pxd +15 -0
- sage/rings/finite_rings/hom_prime_finite_field.pyx +164 -0
- sage/rings/finite_rings/homset.py +357 -0
- sage/rings/finite_rings/integer_mod.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/integer_mod.pxd +56 -0
- sage/rings/finite_rings/integer_mod.pyx +4586 -0
- sage/rings/finite_rings/integer_mod_limits.h +11 -0
- sage/rings/finite_rings/integer_mod_ring.py +2044 -0
- sage/rings/finite_rings/residue_field.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/residue_field.pxd +30 -0
- sage/rings/finite_rings/residue_field.pyx +1811 -0
- sage/rings/finite_rings/stdint.pxd +19 -0
- sage/rings/fraction_field.py +1452 -0
- sage/rings/fraction_field_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/fraction_field_element.pyx +1357 -0
- sage/rings/function_field/all.py +7 -0
- sage/rings/function_field/all__sagemath_categories.py +2 -0
- sage/rings/function_field/constructor.py +218 -0
- sage/rings/function_field/element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/function_field/element.pxd +11 -0
- sage/rings/function_field/element.pyx +1008 -0
- sage/rings/function_field/element_rational.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/function_field/element_rational.pyx +513 -0
- sage/rings/function_field/extensions.py +230 -0
- sage/rings/function_field/function_field.py +1468 -0
- sage/rings/function_field/function_field_rational.py +1005 -0
- sage/rings/function_field/ideal.py +1155 -0
- sage/rings/function_field/ideal_rational.py +629 -0
- sage/rings/function_field/jacobian_base.py +826 -0
- sage/rings/function_field/jacobian_hess.py +1053 -0
- sage/rings/function_field/jacobian_khuri_makdisi.py +1027 -0
- sage/rings/function_field/maps.py +1039 -0
- sage/rings/function_field/order.py +281 -0
- sage/rings/function_field/order_basis.py +586 -0
- sage/rings/function_field/order_rational.py +576 -0
- sage/rings/function_field/place.py +426 -0
- sage/rings/function_field/place_rational.py +181 -0
- sage/rings/generic.py +320 -0
- sage/rings/homset.py +332 -0
- sage/rings/ideal.py +1885 -0
- sage/rings/ideal_monoid.py +215 -0
- sage/rings/infinity.py +1890 -0
- sage/rings/integer.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/integer.pxd +45 -0
- sage/rings/integer.pyx +7874 -0
- sage/rings/integer_ring.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/integer_ring.pxd +8 -0
- sage/rings/integer_ring.pyx +1693 -0
- sage/rings/laurent_series_ring.py +931 -0
- sage/rings/laurent_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/laurent_series_ring_element.pxd +11 -0
- sage/rings/laurent_series_ring_element.pyx +1927 -0
- sage/rings/lazy_series.py +7815 -0
- sage/rings/lazy_series_ring.py +4356 -0
- sage/rings/localization.py +1043 -0
- sage/rings/morphism.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/morphism.pxd +39 -0
- sage/rings/morphism.pyx +3299 -0
- sage/rings/multi_power_series_ring.py +1145 -0
- sage/rings/multi_power_series_ring_element.py +2184 -0
- sage/rings/noncommutative_ideals.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/noncommutative_ideals.pyx +423 -0
- sage/rings/number_field/all__sagemath_categories.py +1 -0
- sage/rings/number_field/number_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/number_field/number_field_base.pxd +8 -0
- sage/rings/number_field/number_field_base.pyx +507 -0
- sage/rings/number_field/number_field_element_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/number_field/number_field_element_base.pxd +6 -0
- sage/rings/number_field/number_field_element_base.pyx +36 -0
- sage/rings/number_field/number_field_ideal.py +3550 -0
- sage/rings/padics/all__sagemath_categories.py +4 -0
- sage/rings/padics/local_generic.py +1670 -0
- sage/rings/padics/local_generic_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/padics/local_generic_element.pxd +5 -0
- sage/rings/padics/local_generic_element.pyx +1017 -0
- sage/rings/padics/misc.py +256 -0
- sage/rings/padics/padic_generic.py +1911 -0
- sage/rings/padics/pow_computer.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/padics/pow_computer.pxd +38 -0
- sage/rings/padics/pow_computer.pyx +671 -0
- sage/rings/padics/precision_error.py +24 -0
- sage/rings/polynomial/all__sagemath_categories.py +25 -0
- sage/rings/polynomial/commutative_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/commutative_polynomial.pxd +6 -0
- sage/rings/polynomial/commutative_polynomial.pyx +24 -0
- sage/rings/polynomial/cyclotomic.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/cyclotomic.pyx +404 -0
- sage/rings/polynomial/flatten.py +711 -0
- sage/rings/polynomial/ideal.py +102 -0
- sage/rings/polynomial/infinite_polynomial_element.py +1768 -0
- sage/rings/polynomial/infinite_polynomial_ring.py +1653 -0
- sage/rings/polynomial/laurent_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/laurent_polynomial.pxd +18 -0
- sage/rings/polynomial/laurent_polynomial.pyx +2190 -0
- sage/rings/polynomial/laurent_polynomial_ideal.py +590 -0
- sage/rings/polynomial/laurent_polynomial_ring.py +832 -0
- sage/rings/polynomial/laurent_polynomial_ring_base.py +708 -0
- sage/rings/polynomial/multi_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/multi_polynomial.pxd +12 -0
- sage/rings/polynomial/multi_polynomial.pyx +3082 -0
- sage/rings/polynomial/multi_polynomial_element.py +2570 -0
- sage/rings/polynomial/multi_polynomial_ideal.py +5771 -0
- sage/rings/polynomial/multi_polynomial_ring.py +947 -0
- sage/rings/polynomial/multi_polynomial_ring_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/multi_polynomial_ring_base.pxd +15 -0
- sage/rings/polynomial/multi_polynomial_ring_base.pyx +1855 -0
- sage/rings/polynomial/multi_polynomial_sequence.py +2204 -0
- sage/rings/polynomial/polydict.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polydict.pxd +45 -0
- sage/rings/polynomial/polydict.pyx +2701 -0
- sage/rings/polynomial/polynomial_compiled.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polynomial_compiled.pxd +59 -0
- sage/rings/polynomial/polynomial_compiled.pyx +509 -0
- sage/rings/polynomial/polynomial_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polynomial_element.pxd +64 -0
- sage/rings/polynomial/polynomial_element.pyx +13255 -0
- sage/rings/polynomial/polynomial_element_generic.py +1637 -0
- sage/rings/polynomial/polynomial_fateman.py +97 -0
- sage/rings/polynomial/polynomial_quotient_ring.py +2465 -0
- sage/rings/polynomial/polynomial_quotient_ring_element.py +779 -0
- sage/rings/polynomial/polynomial_ring.py +3784 -0
- sage/rings/polynomial/polynomial_ring_constructor.py +1051 -0
- sage/rings/polynomial/polynomial_ring_homomorphism.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polynomial_ring_homomorphism.pxd +5 -0
- sage/rings/polynomial/polynomial_ring_homomorphism.pyx +121 -0
- sage/rings/polynomial/polynomial_singular_interface.py +549 -0
- sage/rings/polynomial/symmetric_ideal.py +989 -0
- sage/rings/polynomial/symmetric_reduction.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/symmetric_reduction.pxd +8 -0
- sage/rings/polynomial/symmetric_reduction.pyx +669 -0
- sage/rings/polynomial/term_order.py +2279 -0
- sage/rings/polynomial/toy_buchberger.py +449 -0
- sage/rings/polynomial/toy_d_basis.py +387 -0
- sage/rings/polynomial/toy_variety.py +362 -0
- sage/rings/power_series_mpoly.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/power_series_mpoly.pxd +9 -0
- sage/rings/power_series_mpoly.pyx +161 -0
- sage/rings/power_series_poly.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/power_series_poly.pxd +10 -0
- sage/rings/power_series_poly.pyx +1317 -0
- sage/rings/power_series_ring.py +1441 -0
- sage/rings/power_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/power_series_ring_element.pxd +12 -0
- sage/rings/power_series_ring_element.pyx +3028 -0
- sage/rings/puiseux_series_ring.py +487 -0
- sage/rings/puiseux_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/puiseux_series_ring_element.pxd +7 -0
- sage/rings/puiseux_series_ring_element.pyx +1055 -0
- sage/rings/qqbar_decorators.py +167 -0
- sage/rings/quotient_ring.py +1598 -0
- sage/rings/quotient_ring_element.py +979 -0
- sage/rings/rational.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/rational.pxd +20 -0
- sage/rings/rational.pyx +4284 -0
- sage/rings/rational_field.py +1730 -0
- sage/rings/real_double.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/real_double.pxd +16 -0
- sage/rings/real_double.pyx +2218 -0
- sage/rings/real_lazy.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/real_lazy.pxd +30 -0
- sage/rings/real_lazy.pyx +1773 -0
- sage/rings/ring.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/ring.pxd +30 -0
- sage/rings/ring.pyx +850 -0
- sage/rings/semirings/all.py +3 -0
- sage/rings/semirings/non_negative_integer_semiring.py +107 -0
- sage/rings/semirings/tropical_mpolynomial.py +972 -0
- sage/rings/semirings/tropical_polynomial.py +997 -0
- sage/rings/semirings/tropical_semiring.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/semirings/tropical_semiring.pyx +676 -0
- sage/rings/semirings/tropical_variety.py +1701 -0
- sage/rings/sum_of_squares.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/sum_of_squares.pxd +3 -0
- sage/rings/sum_of_squares.pyx +336 -0
- sage/rings/tests.py +504 -0
- sage/schemes/affine/affine_homset.py +508 -0
- sage/schemes/affine/affine_morphism.py +1574 -0
- sage/schemes/affine/affine_point.py +460 -0
- sage/schemes/affine/affine_rational_point.py +308 -0
- sage/schemes/affine/affine_space.py +1264 -0
- sage/schemes/affine/affine_subscheme.py +592 -0
- sage/schemes/affine/all.py +25 -0
- sage/schemes/all__sagemath_categories.py +5 -0
- sage/schemes/generic/algebraic_scheme.py +2092 -0
- sage/schemes/generic/all.py +5 -0
- sage/schemes/generic/ambient_space.py +400 -0
- sage/schemes/generic/divisor.py +465 -0
- sage/schemes/generic/divisor_group.py +313 -0
- sage/schemes/generic/glue.py +84 -0
- sage/schemes/generic/homset.py +820 -0
- sage/schemes/generic/hypersurface.py +234 -0
- sage/schemes/generic/morphism.py +2107 -0
- sage/schemes/generic/point.py +237 -0
- sage/schemes/generic/scheme.py +1190 -0
- sage/schemes/generic/spec.py +199 -0
- sage/schemes/product_projective/all.py +6 -0
- sage/schemes/product_projective/homset.py +236 -0
- sage/schemes/product_projective/morphism.py +517 -0
- sage/schemes/product_projective/point.py +568 -0
- sage/schemes/product_projective/rational_point.py +550 -0
- sage/schemes/product_projective/space.py +1301 -0
- sage/schemes/product_projective/subscheme.py +466 -0
- sage/schemes/projective/all.py +24 -0
- sage/schemes/projective/proj_bdd_height.py +453 -0
- sage/schemes/projective/projective_homset.py +718 -0
- sage/schemes/projective/projective_morphism.py +2792 -0
- sage/schemes/projective/projective_point.py +1484 -0
- sage/schemes/projective/projective_rational_point.py +569 -0
- sage/schemes/projective/projective_space.py +2571 -0
- sage/schemes/projective/projective_subscheme.py +1574 -0
- sage/sets/all.py +17 -0
- sage/sets/cartesian_product.py +376 -0
- sage/sets/condition_set.py +525 -0
- sage/sets/disjoint_set.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/sets/disjoint_set.pxd +36 -0
- sage/sets/disjoint_set.pyx +998 -0
- sage/sets/disjoint_union_enumerated_sets.py +625 -0
- sage/sets/family.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/sets/family.pxd +12 -0
- sage/sets/family.pyx +1556 -0
- sage/sets/finite_enumerated_set.py +406 -0
- sage/sets/finite_set_map_cy.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/sets/finite_set_map_cy.pxd +34 -0
- sage/sets/finite_set_map_cy.pyx +708 -0
- sage/sets/finite_set_maps.py +591 -0
- sage/sets/image_set.py +448 -0
- sage/sets/integer_range.py +829 -0
- sage/sets/non_negative_integers.py +241 -0
- sage/sets/positive_integers.py +93 -0
- sage/sets/primes.py +188 -0
- sage/sets/real_set.py +2760 -0
- sage/sets/recursively_enumerated_set.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/sets/recursively_enumerated_set.pxd +31 -0
- sage/sets/recursively_enumerated_set.pyx +2082 -0
- sage/sets/set.py +2083 -0
- sage/sets/set_from_iterator.py +1021 -0
- sage/sets/totally_ordered_finite_set.py +329 -0
- sage/symbolic/all__sagemath_categories.py +1 -0
- sage/symbolic/function.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/symbolic/function.pxd +29 -0
- sage/symbolic/function.pyx +1488 -0
- sage/symbolic/symbols.py +56 -0
- sage/tests/all__sagemath_categories.py +1 -0
- sage/tests/cython.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/tests/cython.pyx +37 -0
- sage/tests/stl_vector.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/tests/stl_vector.pyx +171 -0
- sage/typeset/all.py +6 -0
- sage/typeset/ascii_art.py +295 -0
- sage/typeset/character_art.py +789 -0
- sage/typeset/character_art_factory.py +572 -0
- sage/typeset/symbols.py +334 -0
- sage/typeset/unicode_art.py +183 -0
- sage/typeset/unicode_characters.py +101 -0
|
@@ -0,0 +1,997 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-categories
|
|
2
|
+
# sage.doctest: needs sage.symbolic
|
|
3
|
+
r"""
|
|
4
|
+
Univariate Tropical Polynomials
|
|
5
|
+
|
|
6
|
+
AUTHORS:
|
|
7
|
+
|
|
8
|
+
- Verrel Rievaldo Wijaya (2024-06): initial version
|
|
9
|
+
|
|
10
|
+
EXAMPLES::
|
|
11
|
+
|
|
12
|
+
sage: T = TropicalSemiring(QQ, use_min=False)
|
|
13
|
+
sage: R.<x> = PolynomialRing(T)
|
|
14
|
+
sage: x.parent()
|
|
15
|
+
Univariate Tropical Polynomial Semiring in x over Rational Field
|
|
16
|
+
sage: (x + R(3)*x) * (x^2 + x)
|
|
17
|
+
3*x^3 + 3*x^2
|
|
18
|
+
sage: (x^2 + R(1)*x + R(-1))^2
|
|
19
|
+
0*x^4 + 1*x^3 + 2*x^2 + 0*x + (-2)
|
|
20
|
+
sage: (x^2 + x + R(0))^4
|
|
21
|
+
0*x^8 + 0*x^7 + 0*x^6 + 0*x^5 + 0*x^4 + 0*x^3 + 0*x^2 + 0*x + 0
|
|
22
|
+
|
|
23
|
+
REFERENCES:
|
|
24
|
+
|
|
25
|
+
- [Bru2014]_
|
|
26
|
+
- [Fil2017]_
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
# ****************************************************************************
|
|
30
|
+
# Copyright (C) 2024 Verrel Rievaldo Wijaya <verrelrievaldo@gmail.com>
|
|
31
|
+
#
|
|
32
|
+
# This program is free software: you can redistribute it and/or modify
|
|
33
|
+
# it under the terms of the GNU General Public License as published by
|
|
34
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
35
|
+
# (at your option) any later version.
|
|
36
|
+
# https://www.gnu.org/licenses/
|
|
37
|
+
# ****************************************************************************
|
|
38
|
+
|
|
39
|
+
from sage.misc.cachefunc import cached_method
|
|
40
|
+
from sage.rings.polynomial.polynomial_element_generic import Polynomial_generic_sparse
|
|
41
|
+
from sage.structure.parent import Parent
|
|
42
|
+
from sage.structure.unique_representation import UniqueRepresentation
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class TropicalPolynomial(Polynomial_generic_sparse):
|
|
46
|
+
r"""
|
|
47
|
+
A univariate tropical polynomial.
|
|
48
|
+
|
|
49
|
+
A tropical polynomial is a polynomial whose coefficients come from
|
|
50
|
+
a tropical semiring. Tropical polynomial induces a function which is
|
|
51
|
+
piecewise linear, where each segment of the function has a non-negative
|
|
52
|
+
integer slope. Tropical roots (zeros) of polynomial `P(x)` is defined
|
|
53
|
+
as all points `x_0` for which the graph of `P(x)` change its slope.
|
|
54
|
+
The difference in the slopes of the two pieces adjacent to this root
|
|
55
|
+
gives the order of the root.
|
|
56
|
+
|
|
57
|
+
The tropical polynomials are implemented with a sparse format by using
|
|
58
|
+
a ``dict`` whose keys are the exponent and values the corresponding
|
|
59
|
+
coefficients. Each coefficient is a tropical number.
|
|
60
|
+
|
|
61
|
+
EXAMPLES:
|
|
62
|
+
|
|
63
|
+
We construct a tropical polynomial semiring by defining a base
|
|
64
|
+
tropical semiring and then inputting it to :class:`PolynomialRing`::
|
|
65
|
+
|
|
66
|
+
sage: T = TropicalSemiring(QQ, use_min=False)
|
|
67
|
+
sage: R.<x> = PolynomialRing(T); R
|
|
68
|
+
Univariate Tropical Polynomial Semiring in x over Rational Field
|
|
69
|
+
sage: R.0
|
|
70
|
+
0*x
|
|
71
|
+
|
|
72
|
+
One way to construct an element is to provide a list or tuple of
|
|
73
|
+
coefficients. Another way to define an element is to write a polynomial
|
|
74
|
+
equation with each coefficient converted to the semiring::
|
|
75
|
+
|
|
76
|
+
sage: p1 = R([1,4,None,0]); p1
|
|
77
|
+
0*x^3 + 4*x + 1
|
|
78
|
+
sage: p2 = R(1)*x^2 + R(2)*x + R(3); p2
|
|
79
|
+
1*x^2 + 2*x + 3
|
|
80
|
+
|
|
81
|
+
We can do some basic arithmetic operations for these tropical polynomials.
|
|
82
|
+
Remember that numbers given have to be in the tropical semiring.
|
|
83
|
+
If not, then it will raise an error::
|
|
84
|
+
|
|
85
|
+
sage: p1 + p2
|
|
86
|
+
0*x^3 + 1*x^2 + 4*x + 3
|
|
87
|
+
sage: p1 * p2
|
|
88
|
+
1*x^5 + 2*x^4 + 5*x^3 + 6*x^2 + 7*x + 4
|
|
89
|
+
sage: 2 * p1
|
|
90
|
+
Traceback (most recent call last):
|
|
91
|
+
...
|
|
92
|
+
ArithmeticError: cannot negate any non-infinite element
|
|
93
|
+
sage: T(2) * p1
|
|
94
|
+
2*x^3 + 6*x + 3
|
|
95
|
+
sage: p1(3)
|
|
96
|
+
Traceback (most recent call last):
|
|
97
|
+
...
|
|
98
|
+
TypeError: no common canonical parent for objects with parents:
|
|
99
|
+
'Tropical semiring over Rational Field' and 'Integer Ring'
|
|
100
|
+
sage: p1(T(3))
|
|
101
|
+
9
|
|
102
|
+
|
|
103
|
+
We can find all tropical roots of a tropical polynomial, counted
|
|
104
|
+
with their multiplicities::
|
|
105
|
+
|
|
106
|
+
sage: p1.roots()
|
|
107
|
+
[-3, 2, 2]
|
|
108
|
+
sage: p2.roots()
|
|
109
|
+
[1, 1]
|
|
110
|
+
|
|
111
|
+
Even though every tropical polynomials have tropical roots, this does not
|
|
112
|
+
necessarily means it can be factored into its linear factors::
|
|
113
|
+
|
|
114
|
+
sage: p1.factor()
|
|
115
|
+
(0) * (0*x^3 + 4*x + 1)
|
|
116
|
+
sage: p2.factor()
|
|
117
|
+
(1) * (0*x + 1)^2
|
|
118
|
+
|
|
119
|
+
Every tropical polynomial `p(x)` have a corresponding unique tropical
|
|
120
|
+
polynomial `\bar{p}(x)` with the same roots that can be factored. We
|
|
121
|
+
call `\bar{p}(x)` the tropical polynomial split form of `p(x)`::
|
|
122
|
+
|
|
123
|
+
sage: p1.split_form()
|
|
124
|
+
0*x^3 + 2*x^2 + 4*x + 1
|
|
125
|
+
sage: p2.split_form()
|
|
126
|
+
1*x^2 + 2*x + 3
|
|
127
|
+
|
|
128
|
+
Every tropical polynomial induce a piecewise linear function that can be
|
|
129
|
+
invoked in the following way::
|
|
130
|
+
|
|
131
|
+
sage: p1.piecewise_function()
|
|
132
|
+
piecewise(x|-->1 on (-oo, -3], x|-->x + 4 on (-3, 2), x|-->3*x on [2, +oo); x)
|
|
133
|
+
sage: p1.plot() # needs sage.plot
|
|
134
|
+
Graphics object consisting of 1 graphics primitive
|
|
135
|
+
|
|
136
|
+
.. PLOT::
|
|
137
|
+
:width: 300 px
|
|
138
|
+
|
|
139
|
+
T = TropicalSemiring(QQ, use_min=False)
|
|
140
|
+
R = PolynomialRing(T, 'x')
|
|
141
|
+
p1 = R([1,4,None,0])
|
|
142
|
+
sphinx_plot(p1.plot())
|
|
143
|
+
|
|
144
|
+
::
|
|
145
|
+
|
|
146
|
+
sage: p2.piecewise_function()
|
|
147
|
+
piecewise(x|-->3 on (-oo, 1], x|-->2*x + 1 on (1, +oo); x)
|
|
148
|
+
sage: p2.plot() # needs sage.plot
|
|
149
|
+
Graphics object consisting of 1 graphics primitive
|
|
150
|
+
|
|
151
|
+
.. PLOT::
|
|
152
|
+
:width: 300 px
|
|
153
|
+
|
|
154
|
+
T = TropicalSemiring(QQ, use_min=False)
|
|
155
|
+
R = PolynomialRing(T, 'x')
|
|
156
|
+
x = R.gen()
|
|
157
|
+
p2 = R(1)*x**2 + R(2)*x + R(3)
|
|
158
|
+
sphinx_plot(plot(p2, xmin=-1, xmax=3))
|
|
159
|
+
|
|
160
|
+
TESTS:
|
|
161
|
+
|
|
162
|
+
There is no subtraction for tropical polynomials because element in
|
|
163
|
+
tropical semiring doesn't necessarily have additive inverse::
|
|
164
|
+
|
|
165
|
+
sage: -p1
|
|
166
|
+
Traceback (most recent call last):
|
|
167
|
+
...
|
|
168
|
+
ArithmeticError: cannot negate any non-infinite element
|
|
169
|
+
"""
|
|
170
|
+
def roots(self):
|
|
171
|
+
r"""
|
|
172
|
+
Return the list of all tropical roots of ``self``, counted with
|
|
173
|
+
multiplicity.
|
|
174
|
+
|
|
175
|
+
OUTPUT: a list of tropical numbers
|
|
176
|
+
|
|
177
|
+
ALGORITHM:
|
|
178
|
+
|
|
179
|
+
For each pair of monomials in the polynomial, we find the point
|
|
180
|
+
where their values are equal. This is the same as solving the
|
|
181
|
+
equation `c_1 + a_1 \cdot x = c_2 + a_2 \cdot x` for `x`, where
|
|
182
|
+
`(c_1, a_1)` and `(c_2, a_2)` are the coefficients and exponents
|
|
183
|
+
of monomials.
|
|
184
|
+
|
|
185
|
+
The solution to this equation is `x = (c_2-c_1)/(a_1-a_2)`. We
|
|
186
|
+
substitute this `x` to each monomials in polynomial and check if
|
|
187
|
+
the maximum (minimum) is achieved by the previous two monomials.
|
|
188
|
+
If it is, then `x` is the root of tropical polynomial. In this
|
|
189
|
+
case, the order of the root at `x` is the maximum of `|i-j|` for
|
|
190
|
+
all possible pairs `i,j` which realise this maximum (minimum).
|
|
191
|
+
|
|
192
|
+
EXAMPLES::
|
|
193
|
+
|
|
194
|
+
sage: T = TropicalSemiring(QQ, use_min=True)
|
|
195
|
+
sage: R.<x> = PolynomialRing(T)
|
|
196
|
+
sage: p1 = R([5,4,1,0,2,4,3]); p1
|
|
197
|
+
3*x^6 + 4*x^5 + 2*x^4 + 0*x^3 + 1*x^2 + 4*x + 5
|
|
198
|
+
sage: p1.roots()
|
|
199
|
+
[-1, -1, -1, 1, 2, 2]
|
|
200
|
+
|
|
201
|
+
There will be no tropical root for constant polynomial. Additionaly,
|
|
202
|
+
for a monomial, the tropical root is assumed to be the additive
|
|
203
|
+
identity of its base tropical semiring::
|
|
204
|
+
|
|
205
|
+
sage: p2 = R(2)
|
|
206
|
+
sage: p2.roots()
|
|
207
|
+
[]
|
|
208
|
+
sage: p3 = x^3
|
|
209
|
+
sage: p3.roots()
|
|
210
|
+
[+infinity, +infinity, +infinity]
|
|
211
|
+
"""
|
|
212
|
+
from itertools import combinations
|
|
213
|
+
tropical_roots = []
|
|
214
|
+
data = self.monomial_coefficients()
|
|
215
|
+
R = self.parent().base()
|
|
216
|
+
if len(data) == 1:
|
|
217
|
+
exponent = next(iter(data))
|
|
218
|
+
if not exponent:
|
|
219
|
+
return tropical_roots
|
|
220
|
+
return [R.zero()] * exponent
|
|
221
|
+
dict_root = {}
|
|
222
|
+
dict_coeff = {i: c.lift() for i, c in data.items()}
|
|
223
|
+
for comb in combinations(dict_coeff, 2):
|
|
224
|
+
index1, index2 = comb[0], comb[1]
|
|
225
|
+
root = (dict_coeff[index1]-dict_coeff[index2]) / (index2-index1)
|
|
226
|
+
val_root = dict_coeff[index1] + index1*root
|
|
227
|
+
check_maks = True
|
|
228
|
+
for key in dict_coeff:
|
|
229
|
+
if key not in comb:
|
|
230
|
+
val = dict_coeff[key] + key*root
|
|
231
|
+
if R._use_min:
|
|
232
|
+
if val < val_root:
|
|
233
|
+
check_maks = False
|
|
234
|
+
break
|
|
235
|
+
elif val > val_root:
|
|
236
|
+
check_maks = False
|
|
237
|
+
break
|
|
238
|
+
if check_maks:
|
|
239
|
+
order = abs(index1-index2)
|
|
240
|
+
if root not in dict_root:
|
|
241
|
+
dict_root[root] = order
|
|
242
|
+
elif order > dict_root[root]:
|
|
243
|
+
dict_root[root] = order
|
|
244
|
+
for root in dict_root:
|
|
245
|
+
tropical_roots += [root] * dict_root[root]
|
|
246
|
+
return sorted(tropical_roots)
|
|
247
|
+
|
|
248
|
+
def split_form(self):
|
|
249
|
+
r"""
|
|
250
|
+
Return the tropical polynomial which has the same roots as ``self``
|
|
251
|
+
but which can be reduced to its linear factors.
|
|
252
|
+
|
|
253
|
+
If a tropical polynomial has roots at `x_1, x_2, \ldots, x_n`, then
|
|
254
|
+
its split form is the tropical product of linear terms of the form
|
|
255
|
+
`(x + x_i)` for all `i=1,2,\ldots,n`.
|
|
256
|
+
|
|
257
|
+
OUTPUT: :class:`TropicalPolynomial`
|
|
258
|
+
|
|
259
|
+
EXAMPLES::
|
|
260
|
+
|
|
261
|
+
sage: T = TropicalSemiring(QQ, use_min=True)
|
|
262
|
+
sage: R.<x> = PolynomialRing(T)
|
|
263
|
+
sage: p1 = R([5,4,1,0,2,4,3]); p1
|
|
264
|
+
3*x^6 + 4*x^5 + 2*x^4 + 0*x^3 + 1*x^2 + 4*x + 5
|
|
265
|
+
sage: p1.split_form()
|
|
266
|
+
3*x^6 + 2*x^5 + 1*x^4 + 0*x^3 + 1*x^2 + 3*x + 5
|
|
267
|
+
|
|
268
|
+
::
|
|
269
|
+
|
|
270
|
+
sage: T = TropicalSemiring(QQ, use_min=False)
|
|
271
|
+
sage: R.<x> = PolynomialRing(T)
|
|
272
|
+
sage: p1 = R([5,4,1,0,2,4,3])
|
|
273
|
+
sage: p1.split_form()
|
|
274
|
+
3*x^6 + 4*x^5 + 21/5*x^4 + 22/5*x^3 + 23/5*x^2 + 24/5*x + 5
|
|
275
|
+
|
|
276
|
+
TESTS:
|
|
277
|
+
|
|
278
|
+
We verify that the roots of tropical polynomial and its split form
|
|
279
|
+
is really the same::
|
|
280
|
+
|
|
281
|
+
sage: p1.roots() == p1.split_form().roots()
|
|
282
|
+
True
|
|
283
|
+
"""
|
|
284
|
+
roots = self.roots()
|
|
285
|
+
R = self.parent()
|
|
286
|
+
poly = R(self.monomial_coefficients()[self.degree()].lift())
|
|
287
|
+
for root in roots:
|
|
288
|
+
linear = R([root, 0])
|
|
289
|
+
poly *= linear
|
|
290
|
+
return poly
|
|
291
|
+
|
|
292
|
+
def factor(self):
|
|
293
|
+
r"""
|
|
294
|
+
Return the factorization of ``self`` into its tropical linear factors.
|
|
295
|
+
|
|
296
|
+
Note that the factor `x - x_0` in classical algebra gets transformed
|
|
297
|
+
to the factor `x + x_0`, since the root of the tropical polynomial
|
|
298
|
+
`x + x_0` is `x_0` and not `-x_0`. However, not every tropical
|
|
299
|
+
polynomial can be factored.
|
|
300
|
+
|
|
301
|
+
OUTPUT: :class:'Factorization'
|
|
302
|
+
|
|
303
|
+
EXAMPLES::
|
|
304
|
+
|
|
305
|
+
sage: T = TropicalSemiring(QQ, use_min=True)
|
|
306
|
+
sage: R.<x> = PolynomialRing(T)
|
|
307
|
+
sage: p1 = R([6,3,1,0]); p1
|
|
308
|
+
0*x^3 + 1*x^2 + 3*x + 6
|
|
309
|
+
sage: factor(p1)
|
|
310
|
+
(0) * (0*x + 1) * (0*x + 2) * (0*x + 3)
|
|
311
|
+
|
|
312
|
+
Such factorization is not always possible::
|
|
313
|
+
|
|
314
|
+
sage: p2 = R([4,4,2]); p2
|
|
315
|
+
2*x^2 + 4*x + 4
|
|
316
|
+
sage: p2.factor()
|
|
317
|
+
(2) * (0*x^2 + 2*x + 2)
|
|
318
|
+
|
|
319
|
+
TESTS:
|
|
320
|
+
|
|
321
|
+
The factorization for a constant::
|
|
322
|
+
|
|
323
|
+
sage: p3 = R(3)
|
|
324
|
+
sage: p3.factor()
|
|
325
|
+
(3) * 0
|
|
326
|
+
"""
|
|
327
|
+
from sage.structure.factorization import Factorization
|
|
328
|
+
unit = self.monomial_coefficients()[self.degree()]
|
|
329
|
+
if self != self.split_form() or not self.roots():
|
|
330
|
+
factor = [(self * self.parent(-unit.lift()), 1)]
|
|
331
|
+
return Factorization(factor, unit=unit)
|
|
332
|
+
|
|
333
|
+
R = self.parent()
|
|
334
|
+
roots_order = {}
|
|
335
|
+
for root in self.roots():
|
|
336
|
+
if root in roots_order:
|
|
337
|
+
roots_order[root] += 1
|
|
338
|
+
else:
|
|
339
|
+
roots_order[root] = 1
|
|
340
|
+
factors = [(R([root, 0]), roots_order[root])
|
|
341
|
+
for root in roots_order]
|
|
342
|
+
return Factorization(factors, unit=unit)
|
|
343
|
+
|
|
344
|
+
def piecewise_function(self):
|
|
345
|
+
r"""
|
|
346
|
+
Return the tropical polynomial function of ``self``.
|
|
347
|
+
|
|
348
|
+
The function is a piecewise linear function with the domains are
|
|
349
|
+
divided by the roots. First we convert each term of polynomial to
|
|
350
|
+
its corresponding linear function. Next, we must determine which
|
|
351
|
+
term achieves the minimum (maximum) at each interval.
|
|
352
|
+
|
|
353
|
+
OUTPUT: a piecewise function
|
|
354
|
+
|
|
355
|
+
EXAMPLES::
|
|
356
|
+
|
|
357
|
+
sage: T = TropicalSemiring(QQ, use_min=False)
|
|
358
|
+
sage: R.<x> = PolynomialRing(T)
|
|
359
|
+
sage: p1 = R([4,2,1,3]); p1
|
|
360
|
+
3*x^3 + 1*x^2 + 2*x + 4
|
|
361
|
+
sage: p1.piecewise_function()
|
|
362
|
+
piecewise(x|-->4 on (-oo, 1/3], x|-->3*x + 3 on (1/3, +oo); x)
|
|
363
|
+
|
|
364
|
+
A constant tropical polynomial will result in a constant function::
|
|
365
|
+
|
|
366
|
+
sage: p2 = R(3)
|
|
367
|
+
sage: p2.piecewise_function()
|
|
368
|
+
3
|
|
369
|
+
|
|
370
|
+
A monomial will resulted in a linear function::
|
|
371
|
+
|
|
372
|
+
sage: p3 = R(1)*x^3
|
|
373
|
+
sage: p3.piecewise_function()
|
|
374
|
+
3*x + 1
|
|
375
|
+
"""
|
|
376
|
+
from sage.functions.piecewise import piecewise
|
|
377
|
+
from sage.sets.real_set import RealSet
|
|
378
|
+
from sage.symbolic.ring import SR
|
|
379
|
+
|
|
380
|
+
x = SR.var('x')
|
|
381
|
+
data = self.monomial_coefficients()
|
|
382
|
+
R = self.parent().base()
|
|
383
|
+
if not self.roots():
|
|
384
|
+
f = data[0].lift()
|
|
385
|
+
return f
|
|
386
|
+
|
|
387
|
+
if len(data) == 1:
|
|
388
|
+
gradient = list(data)[0]
|
|
389
|
+
intercept = data[gradient].lift()
|
|
390
|
+
f = intercept + gradient*x
|
|
391
|
+
return f
|
|
392
|
+
|
|
393
|
+
unique_root = sorted(set(self.roots()))
|
|
394
|
+
pieces = []
|
|
395
|
+
domain = []
|
|
396
|
+
for i in range(len(unique_root) + 1):
|
|
397
|
+
if i == 0:
|
|
398
|
+
test_number = R(unique_root[i] - 1)
|
|
399
|
+
elif i == len(unique_root):
|
|
400
|
+
test_number = R(unique_root[i-1] + 1)
|
|
401
|
+
else:
|
|
402
|
+
test_number = R((unique_root[i]+unique_root[i-1]) / 2)
|
|
403
|
+
terms = {i: c * test_number**i for i, c in data.items()}
|
|
404
|
+
if R._use_min:
|
|
405
|
+
critical = min(terms.values())
|
|
406
|
+
else:
|
|
407
|
+
critical = max(terms.values())
|
|
408
|
+
found_key = None
|
|
409
|
+
for key, value in terms.items():
|
|
410
|
+
if value == critical:
|
|
411
|
+
found_key = key
|
|
412
|
+
break
|
|
413
|
+
gradient = found_key
|
|
414
|
+
intercept = data[found_key].lift()
|
|
415
|
+
|
|
416
|
+
# To make sure all roots is included in the domain
|
|
417
|
+
if i == 0:
|
|
418
|
+
interval = RealSet.unbounded_below_closed(unique_root[i])
|
|
419
|
+
piecewise_linear = (interval, intercept + gradient*x)
|
|
420
|
+
domain.append(interval)
|
|
421
|
+
elif i == len(unique_root):
|
|
422
|
+
if domain[i-1][0].upper_closed():
|
|
423
|
+
interval = RealSet.unbounded_above_open(unique_root[i-1])
|
|
424
|
+
else:
|
|
425
|
+
interval = RealSet.unbounded_above_closed(unique_root[i-1])
|
|
426
|
+
piecewise_linear = (interval, intercept + gradient*x)
|
|
427
|
+
domain.append(interval)
|
|
428
|
+
else:
|
|
429
|
+
if domain[i-1][0].upper_closed():
|
|
430
|
+
interval = RealSet((unique_root[i-1], unique_root[i]))
|
|
431
|
+
else:
|
|
432
|
+
interval = RealSet([unique_root[i-1], unique_root[i]])
|
|
433
|
+
piecewise_linear = (interval, intercept + gradient*x)
|
|
434
|
+
domain.append(interval)
|
|
435
|
+
pieces.append(piecewise_linear)
|
|
436
|
+
|
|
437
|
+
f = piecewise(pieces)
|
|
438
|
+
return f
|
|
439
|
+
|
|
440
|
+
def plot(self, xmin=None, xmax=None):
|
|
441
|
+
r"""
|
|
442
|
+
Return the plot of ``self``, which is the tropical polynomial
|
|
443
|
+
function we get from ``self.piecewise_function()``.
|
|
444
|
+
|
|
445
|
+
INPUT:
|
|
446
|
+
|
|
447
|
+
- ``xmin`` -- (optional) real number
|
|
448
|
+
- ``xmax`` -- (optional) real number
|
|
449
|
+
|
|
450
|
+
OUTPUT:
|
|
451
|
+
|
|
452
|
+
If ``xmin`` and ``xmax`` is given, then it return a plot of
|
|
453
|
+
piecewise linear function of ``self`` with the axes start from
|
|
454
|
+
``xmin`` to ``xmax``. Otherwise, the domain will start from the
|
|
455
|
+
the minimum root of ``self`` minus 1 to maximum root of ``self``
|
|
456
|
+
plus 1. If the function of ``self`` is constant or linear, then
|
|
457
|
+
the default domain will be `[-1,1]`.
|
|
458
|
+
|
|
459
|
+
EXAMPLES:
|
|
460
|
+
|
|
461
|
+
If the tropical semiring use a max-plus algebra, then the graph
|
|
462
|
+
will be of piecewise linear convex function::
|
|
463
|
+
|
|
464
|
+
sage: T = TropicalSemiring(QQ, use_min=False)
|
|
465
|
+
sage: R.<x> = PolynomialRing(T)
|
|
466
|
+
sage: p1 = R([4,2,1,3]); p1
|
|
467
|
+
3*x^3 + 1*x^2 + 2*x + 4
|
|
468
|
+
sage: p1.roots()
|
|
469
|
+
[1/3, 1/3, 1/3]
|
|
470
|
+
sage: p1.plot() # needs sage.plot
|
|
471
|
+
Graphics object consisting of 1 graphics primitive
|
|
472
|
+
|
|
473
|
+
.. PLOT::
|
|
474
|
+
:width: 300 px
|
|
475
|
+
|
|
476
|
+
T = TropicalSemiring(QQ, use_min=False)
|
|
477
|
+
R = PolynomialRing(T, 'x')
|
|
478
|
+
p1 = R([4,2,1,3])
|
|
479
|
+
sphinx_plot(p1.plot())
|
|
480
|
+
|
|
481
|
+
A different result will be obtained if the tropical semiring employs
|
|
482
|
+
a min-plus algebra. Rather, a graph of the piecewise linear concave
|
|
483
|
+
function will be obtained::
|
|
484
|
+
|
|
485
|
+
sage: T = TropicalSemiring(QQ, use_min=True)
|
|
486
|
+
sage: R.<x> = PolynomialRing(T)
|
|
487
|
+
sage: p1 = R([4,2,1,3])
|
|
488
|
+
sage: p1.roots()
|
|
489
|
+
[-2, 1, 2]
|
|
490
|
+
sage: p1.plot() # needs sage.plot
|
|
491
|
+
Graphics object consisting of 1 graphics primitive
|
|
492
|
+
|
|
493
|
+
.. PLOT::
|
|
494
|
+
:width: 300 px
|
|
495
|
+
|
|
496
|
+
T = TropicalSemiring(QQ, use_min=True)
|
|
497
|
+
R = PolynomialRing(T, 'x')
|
|
498
|
+
p1 = R([4,2,1,3])
|
|
499
|
+
sphinx_plot(p1.plot())
|
|
500
|
+
|
|
501
|
+
TESTS:
|
|
502
|
+
|
|
503
|
+
If ``xmin`` or ``xmax`` is given as an input, then the others also
|
|
504
|
+
have to be given. Otherwise it will raise an error::
|
|
505
|
+
|
|
506
|
+
sage: plot(p1, 5) # needs sage.plot
|
|
507
|
+
Traceback (most recent call last):
|
|
508
|
+
...
|
|
509
|
+
ValueError: expected 2 inputs for xmin and xmax, but got 1
|
|
510
|
+
|
|
511
|
+
Error also occurred when ``xmin`` is greater or equal than``xmax``::
|
|
512
|
+
|
|
513
|
+
sage: plot(p1, 5, 3) # needs sage.plot
|
|
514
|
+
Traceback (most recent call last):
|
|
515
|
+
...
|
|
516
|
+
ValueError: xmin = 5 should be less than xmax = 3
|
|
517
|
+
"""
|
|
518
|
+
from sage.plot.plot import plot
|
|
519
|
+
f = self.piecewise_function()
|
|
520
|
+
if (xmin is None) and (xmax is None):
|
|
521
|
+
roots = sorted(self.roots())
|
|
522
|
+
if (not roots) or (self.parent().base().zero() in roots):
|
|
523
|
+
return plot(f, xmin=-1, xmax=1)
|
|
524
|
+
else:
|
|
525
|
+
return plot(f, xmin=roots[0]-1, xmax=roots[-1]+1)
|
|
526
|
+
elif xmin is None or xmax is None:
|
|
527
|
+
raise ValueError("expected 2 inputs for xmin and xmax, but got 1")
|
|
528
|
+
elif xmin >= xmax:
|
|
529
|
+
raise ValueError(f"xmin = {xmin} should be less than xmax = {xmax}")
|
|
530
|
+
return plot(f, xmin=xmin, xmax=xmax)
|
|
531
|
+
|
|
532
|
+
def _repr_(self):
|
|
533
|
+
r"""
|
|
534
|
+
Return a string representation of ``self``.
|
|
535
|
+
|
|
536
|
+
EXAMPLES::
|
|
537
|
+
|
|
538
|
+
sage: T = TropicalSemiring(QQ)
|
|
539
|
+
sage: R.<x> = PolynomialRing(T)
|
|
540
|
+
sage: R([-3,-1,2,-1])
|
|
541
|
+
(-1)*x^3 + 2*x^2 + (-1)*x + (-3)
|
|
542
|
+
"""
|
|
543
|
+
import re
|
|
544
|
+
if not self.monomial_coefficients():
|
|
545
|
+
return str(self.parent().base().zero())
|
|
546
|
+
|
|
547
|
+
def replace_negatives(expr):
|
|
548
|
+
modified_expr = re.sub(r'(-\d+/\d+|-\d+)', r'(\1)', expr)
|
|
549
|
+
return modified_expr
|
|
550
|
+
|
|
551
|
+
s = super()._repr()
|
|
552
|
+
v = self.parent().variable_name()
|
|
553
|
+
if s[0] == v:
|
|
554
|
+
s = "1*" + s
|
|
555
|
+
s = s.replace(" - ", " + -")
|
|
556
|
+
s = s.replace(" + "+v, " + 1*"+v)
|
|
557
|
+
s = s.replace("-"+v, "-1*"+v)
|
|
558
|
+
s = replace_negatives(s)
|
|
559
|
+
return s
|
|
560
|
+
|
|
561
|
+
def _latex_(self):
|
|
562
|
+
r"""
|
|
563
|
+
Return a latex representation of ``self``.
|
|
564
|
+
|
|
565
|
+
EXAMPLES::
|
|
566
|
+
|
|
567
|
+
sage: T = TropicalSemiring(QQ)
|
|
568
|
+
sage: R = PolynomialRing(T, 'x')
|
|
569
|
+
sage: p1 = R([-1,2,None,-3])
|
|
570
|
+
sage: latex(p1)
|
|
571
|
+
\left(-3\right) x^{3} + 2 x + \left(-1\right)
|
|
572
|
+
"""
|
|
573
|
+
s = " "
|
|
574
|
+
coeffs = self.list(copy=False)
|
|
575
|
+
m = len(coeffs)
|
|
576
|
+
name = self.parent().latex_variable_names()[0]
|
|
577
|
+
for n in reversed(range(m)):
|
|
578
|
+
x = coeffs[n]
|
|
579
|
+
x = x._latex_()
|
|
580
|
+
if x != self.parent().base().zero()._latex_():
|
|
581
|
+
if n != m-1:
|
|
582
|
+
s += " + "
|
|
583
|
+
if x.find("-") == 0:
|
|
584
|
+
x = "\\left(" + x + "\\right)"
|
|
585
|
+
if n > 1:
|
|
586
|
+
v = f"|{name}^{{{n}}}"
|
|
587
|
+
elif n == 1:
|
|
588
|
+
v = f"|{name}"
|
|
589
|
+
else:
|
|
590
|
+
v = ""
|
|
591
|
+
s += f"{x} {v}"
|
|
592
|
+
s = s.replace("|", "")
|
|
593
|
+
if s == " ":
|
|
594
|
+
return self.parent().base().zero()._latex_()
|
|
595
|
+
return s[1:].lstrip().rstrip()
|
|
596
|
+
|
|
597
|
+
|
|
598
|
+
class TropicalPolynomialSemiring(UniqueRepresentation, Parent):
|
|
599
|
+
r"""
|
|
600
|
+
The semiring of univariate tropical polynomials.
|
|
601
|
+
|
|
602
|
+
This is the commutative semiring consisting of finite linear
|
|
603
|
+
combinations of tropical monomials under (tropical)
|
|
604
|
+
addition and multiplication with the identity element
|
|
605
|
+
being `+\infty` (or `-\infty` depending on whether the
|
|
606
|
+
base tropical semiring is using min-plus or max-plus algebra).
|
|
607
|
+
|
|
608
|
+
EXAMPLES::
|
|
609
|
+
|
|
610
|
+
sage: T = TropicalSemiring(QQ)
|
|
611
|
+
sage: R.<x> = PolynomialRing(T)
|
|
612
|
+
sage: f = T(1)*x
|
|
613
|
+
sage: g = T(2)*x
|
|
614
|
+
sage: f + g
|
|
615
|
+
1*x
|
|
616
|
+
sage: f * g
|
|
617
|
+
3*x^2
|
|
618
|
+
sage: f + R.zero() == f
|
|
619
|
+
True
|
|
620
|
+
sage: f * R.zero() == R.zero()
|
|
621
|
+
True
|
|
622
|
+
sage: f * R.one() == f
|
|
623
|
+
True
|
|
624
|
+
"""
|
|
625
|
+
@staticmethod
|
|
626
|
+
def __classcall_private__(cls, base_semiring, names):
|
|
627
|
+
"""
|
|
628
|
+
Ensures the names parameter is a tuple.
|
|
629
|
+
|
|
630
|
+
EXAMPLES::
|
|
631
|
+
|
|
632
|
+
sage: from sage.rings.semirings.tropical_polynomial import TropicalPolynomialSemiring
|
|
633
|
+
sage: T = TropicalSemiring(ZZ)
|
|
634
|
+
sage: TPS = TropicalPolynomialSemiring
|
|
635
|
+
sage: TPS(T, 'x') == TPS(T, ('x'))
|
|
636
|
+
True
|
|
637
|
+
"""
|
|
638
|
+
if isinstance(names, str):
|
|
639
|
+
names = (names,)
|
|
640
|
+
return super().__classcall__(cls, base_semiring, tuple(names))
|
|
641
|
+
|
|
642
|
+
def __init__(self, base_semiring, names):
|
|
643
|
+
r"""
|
|
644
|
+
Initialize ``self``.
|
|
645
|
+
|
|
646
|
+
EXAMPLES::
|
|
647
|
+
|
|
648
|
+
sage: T = TropicalSemiring(QQ)
|
|
649
|
+
sage: R = PolynomialRing(T, 'x')
|
|
650
|
+
sage: TestSuite(R).run()
|
|
651
|
+
|
|
652
|
+
TESTS::
|
|
653
|
+
|
|
654
|
+
sage: from sage.rings.semirings.tropical_polynomial import TropicalPolynomialSemiring
|
|
655
|
+
sage: TropicalPolynomialSemiring(ZZ, names='x')
|
|
656
|
+
Traceback (most recent call last):
|
|
657
|
+
...
|
|
658
|
+
ValueError: Integer Ring is not a tropical semiring
|
|
659
|
+
"""
|
|
660
|
+
from sage.categories.semirings import Semirings
|
|
661
|
+
from sage.rings.semirings.tropical_semiring import TropicalSemiring
|
|
662
|
+
if not isinstance(base_semiring, TropicalSemiring):
|
|
663
|
+
raise ValueError(f"{base_semiring} is not a tropical semiring")
|
|
664
|
+
Parent.__init__(self, base=base_semiring, names=names, category=Semirings())
|
|
665
|
+
|
|
666
|
+
Element = TropicalPolynomial
|
|
667
|
+
|
|
668
|
+
def _element_constructor_(self, x=None, check=True):
|
|
669
|
+
"""
|
|
670
|
+
Convert ``x`` into ``self``, possibly non-canonically.
|
|
671
|
+
|
|
672
|
+
INPUT:
|
|
673
|
+
|
|
674
|
+
- ``x`` -- a list or tuple of coefficients, a polynomial, or a
|
|
675
|
+
dictionary
|
|
676
|
+
|
|
677
|
+
EXAMPLES::
|
|
678
|
+
|
|
679
|
+
sage: T = TropicalSemiring(QQ)
|
|
680
|
+
sage: R = PolynomialRing(T, 'x')
|
|
681
|
+
sage: R([1,2,3])
|
|
682
|
+
3*x^2 + 2*x + 1
|
|
683
|
+
sage: S.<x> = PolynomialRing(QQ)
|
|
684
|
+
sage: R(x^2 - x + 1)
|
|
685
|
+
1*x^2 + (-1)*x + 1
|
|
686
|
+
|
|
687
|
+
If ``x`` is a tropical polynomial from different semiring, then it
|
|
688
|
+
will converted to constant::
|
|
689
|
+
|
|
690
|
+
sage: T = TropicalSemiring(QQ)
|
|
691
|
+
sage: R.<x> = PolynomialRing(T)
|
|
692
|
+
sage: S.<y> = PolynomialRing(T)
|
|
693
|
+
sage: p1 = R(y); p1
|
|
694
|
+
0*y
|
|
695
|
+
sage: p1.parent()
|
|
696
|
+
Univariate Tropical Polynomial Semiring in x over Rational Field
|
|
697
|
+
sage: p1.degree()
|
|
698
|
+
0
|
|
699
|
+
"""
|
|
700
|
+
if isinstance(x, (list, tuple)):
|
|
701
|
+
for i, coeff in enumerate(x):
|
|
702
|
+
if coeff == 0:
|
|
703
|
+
x[i] = self.base().one()
|
|
704
|
+
elif isinstance(x, TropicalPolynomial):
|
|
705
|
+
if x.parent() is not self:
|
|
706
|
+
x = {0: x}
|
|
707
|
+
check = False
|
|
708
|
+
return self.element_class(self, x, check=check)
|
|
709
|
+
|
|
710
|
+
@cached_method
|
|
711
|
+
def one(self):
|
|
712
|
+
"""
|
|
713
|
+
Return the multiplicative identity of ``self``.
|
|
714
|
+
|
|
715
|
+
EXAMPLES::
|
|
716
|
+
|
|
717
|
+
sage: T = TropicalSemiring(QQ)
|
|
718
|
+
sage: R = PolynomialRing(T, 'x')
|
|
719
|
+
sage: R.one()
|
|
720
|
+
0
|
|
721
|
+
"""
|
|
722
|
+
return self.element_class(self, [self.base().one()])
|
|
723
|
+
|
|
724
|
+
@cached_method
|
|
725
|
+
def zero(self):
|
|
726
|
+
"""
|
|
727
|
+
Return the additive identity of ``self``.
|
|
728
|
+
|
|
729
|
+
EXAMPLES::
|
|
730
|
+
|
|
731
|
+
sage: T = TropicalSemiring(QQ)
|
|
732
|
+
sage: R = PolynomialRing(T, 'x')
|
|
733
|
+
sage: R.zero()
|
|
734
|
+
+infinity
|
|
735
|
+
"""
|
|
736
|
+
return self.element_class(self, [self.base().zero()])
|
|
737
|
+
|
|
738
|
+
def _repr_(self):
|
|
739
|
+
"""
|
|
740
|
+
Return a string representation of ``self``.
|
|
741
|
+
|
|
742
|
+
EXAMPLES::
|
|
743
|
+
|
|
744
|
+
sage: T = TropicalSemiring(ZZ)
|
|
745
|
+
sage: R.<abc> = PolynomialRing(T); R
|
|
746
|
+
Univariate Tropical Polynomial Semiring in abc over Integer Ring
|
|
747
|
+
"""
|
|
748
|
+
return (f"Univariate Tropical Polynomial Semiring in {self.variable_name()}"
|
|
749
|
+
f" over {self.base_ring().base_ring()}")
|
|
750
|
+
|
|
751
|
+
def gen(self, n=0):
|
|
752
|
+
"""
|
|
753
|
+
Return the indeterminate generator of ``self``.
|
|
754
|
+
|
|
755
|
+
EXAMPLES::
|
|
756
|
+
|
|
757
|
+
sage: T = TropicalSemiring(QQ)
|
|
758
|
+
sage: R.<abc> = PolynomialRing(T)
|
|
759
|
+
sage: R.gen()
|
|
760
|
+
0*abc
|
|
761
|
+
|
|
762
|
+
TESTS::
|
|
763
|
+
|
|
764
|
+
sage: R.gen(2)
|
|
765
|
+
Traceback (most recent call last):
|
|
766
|
+
...
|
|
767
|
+
IndexError: generator n not defined
|
|
768
|
+
"""
|
|
769
|
+
if n != 0:
|
|
770
|
+
raise IndexError("generator n not defined")
|
|
771
|
+
return self.gens()[n]
|
|
772
|
+
|
|
773
|
+
@cached_method
|
|
774
|
+
def gens(self) -> tuple:
|
|
775
|
+
"""
|
|
776
|
+
Return the generators for ``self``.
|
|
777
|
+
|
|
778
|
+
EXAMPLES::
|
|
779
|
+
|
|
780
|
+
sage: T = TropicalSemiring(QQ)
|
|
781
|
+
sage: R.<abc> = PolynomialRing(T)
|
|
782
|
+
sage: R.gens()
|
|
783
|
+
(0*abc,)
|
|
784
|
+
"""
|
|
785
|
+
R = self.base()
|
|
786
|
+
return (self.element_class(self, [R.zero(), R.one()]),)
|
|
787
|
+
|
|
788
|
+
def ngens(self):
|
|
789
|
+
"""
|
|
790
|
+
Return the number of generators of ``self``, which is 1
|
|
791
|
+
since it is a univariate polynomial ring.
|
|
792
|
+
|
|
793
|
+
EXAMPLES::
|
|
794
|
+
|
|
795
|
+
sage: T = TropicalSemiring(QQ)
|
|
796
|
+
sage: R = PolynomialRing(T, 'x')
|
|
797
|
+
sage: R.ngens()
|
|
798
|
+
1
|
|
799
|
+
"""
|
|
800
|
+
from sage.rings.integer_ring import ZZ
|
|
801
|
+
return ZZ.one()
|
|
802
|
+
|
|
803
|
+
def random_element(self, degree=(-1, 2), monic=False, *args, **kwds):
|
|
804
|
+
r"""
|
|
805
|
+
Return a random tropical polynomial of given degrees (bounds).
|
|
806
|
+
|
|
807
|
+
OUTPUT: :class:`TropicalPolynomial`
|
|
808
|
+
|
|
809
|
+
.. SEEALSO::
|
|
810
|
+
|
|
811
|
+
:meth:`sage.rings.polynomial.polynomial_ring.PolynomialRing_generic.random_element`
|
|
812
|
+
|
|
813
|
+
EXAMPLES:
|
|
814
|
+
|
|
815
|
+
Tropical polynomial over an integer with each coefficient bounded
|
|
816
|
+
between ``x`` and ``y``::
|
|
817
|
+
|
|
818
|
+
sage: T = TropicalSemiring(ZZ)
|
|
819
|
+
sage: R = PolynomialRing(T, 'x')
|
|
820
|
+
sage: f = R.random_element(8, x=3, y=10)
|
|
821
|
+
sage: f.degree()
|
|
822
|
+
8
|
|
823
|
+
sage: f.parent() is R
|
|
824
|
+
True
|
|
825
|
+
sage: all(a >= T(3) for a in f.coefficients())
|
|
826
|
+
True
|
|
827
|
+
sage: all(a < T(10) for a in f.coefficients())
|
|
828
|
+
True
|
|
829
|
+
|
|
830
|
+
If a tuple of two integers is provided for the ``degree`` argument,
|
|
831
|
+
a polynomial is selected with degrees within that range::
|
|
832
|
+
|
|
833
|
+
sage: all(R.random_element(degree=(1, 5)).degree() in range(1, 6) for _ in range(10^3))
|
|
834
|
+
True
|
|
835
|
+
|
|
836
|
+
Note that the zero polynomial (`\pm \infty`) has degree `-1`.
|
|
837
|
+
To include it, set the minimum degree to `-1`::
|
|
838
|
+
|
|
839
|
+
sage: while R.random_element(degree=(-1,2), x=-1, y=1) != R.zero():
|
|
840
|
+
....: pass
|
|
841
|
+
|
|
842
|
+
Monic polynomials are chosen among all monic polynomials with degree
|
|
843
|
+
between the given ``degree`` argument::
|
|
844
|
+
|
|
845
|
+
sage: all(R.random_element(degree=(-1, 2), monic=True).is_monic() for _ in range(10^3))
|
|
846
|
+
True
|
|
847
|
+
"""
|
|
848
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
849
|
+
R = PolynomialRing(self.base().base_ring(), self.variable_names())
|
|
850
|
+
f = R.random_element(degree=degree, monic=monic, *args, **kwds)
|
|
851
|
+
new_dict = f.monomial_coefficients()
|
|
852
|
+
if monic:
|
|
853
|
+
new_dict[f.degree()] = 0
|
|
854
|
+
return self.element_class(self, new_dict)
|
|
855
|
+
|
|
856
|
+
def is_sparse(self):
|
|
857
|
+
"""
|
|
858
|
+
Return ``True`` to indicate that the objects are sparse polynomials.
|
|
859
|
+
|
|
860
|
+
EXAMPLES::
|
|
861
|
+
|
|
862
|
+
sage: T = TropicalSemiring(QQ)
|
|
863
|
+
sage: R = PolynomialRing(T, 'x')
|
|
864
|
+
sage: R.is_sparse()
|
|
865
|
+
True
|
|
866
|
+
"""
|
|
867
|
+
return True
|
|
868
|
+
|
|
869
|
+
def interpolation(self, points):
|
|
870
|
+
"""
|
|
871
|
+
Return a tropical polynomial with its function is a linear
|
|
872
|
+
interpolation of point in ``points`` if possible.
|
|
873
|
+
|
|
874
|
+
If there is only one point, then it will give a constant polynomial.
|
|
875
|
+
Because we are using linear interpolation, each point is actually
|
|
876
|
+
a root of the resulted tropical polynomial.
|
|
877
|
+
|
|
878
|
+
INPUT:
|
|
879
|
+
|
|
880
|
+
- ``points`` -- a list of tuples ``(x, y)``
|
|
881
|
+
|
|
882
|
+
OUTPUT: :class:`TropicalPolynomial`
|
|
883
|
+
|
|
884
|
+
EXAMPLES::
|
|
885
|
+
|
|
886
|
+
sage: T = TropicalSemiring(QQ, use_min=True)
|
|
887
|
+
sage: R = PolynomialRing(T, 'x')
|
|
888
|
+
sage: points = [(-2,-3),(1,3),(2,4)]
|
|
889
|
+
sage: p1 = R.interpolation(points); p1
|
|
890
|
+
1*x^2 + 2*x + 4
|
|
891
|
+
sage: p1.plot() # needs sage.plot
|
|
892
|
+
Graphics object consisting of 1 graphics primitive
|
|
893
|
+
|
|
894
|
+
.. PLOT::
|
|
895
|
+
:width: 300 px
|
|
896
|
+
|
|
897
|
+
T = TropicalSemiring(QQ, use_min=True)
|
|
898
|
+
R = PolynomialRing(T, 'x')
|
|
899
|
+
points = [(-2,-3),(1,3),(2,4)]
|
|
900
|
+
p1 = R.interpolation(points)
|
|
901
|
+
sphinx_plot(p1.plot())
|
|
902
|
+
|
|
903
|
+
::
|
|
904
|
+
|
|
905
|
+
sage: T = TropicalSemiring(QQ, use_min=False)
|
|
906
|
+
sage: R = PolynomialRing(T,'x')
|
|
907
|
+
sage: points = [(0,0),(1,1),(2,4)]
|
|
908
|
+
sage: p1 = R.interpolation(points); p1
|
|
909
|
+
(-2)*x^3 + (-1)*x^2 + 0*x + 0
|
|
910
|
+
sage: p1.plot() # needs sage.plot
|
|
911
|
+
Graphics object consisting of 1 graphics primitive
|
|
912
|
+
|
|
913
|
+
.. PLOT::
|
|
914
|
+
:width: 300 px
|
|
915
|
+
|
|
916
|
+
T = TropicalSemiring(QQ, use_min=False)
|
|
917
|
+
R = PolynomialRing(T, 'x')
|
|
918
|
+
points = [(0,0),(1,1),(2,4)]
|
|
919
|
+
p1 = R.interpolation(points)
|
|
920
|
+
sphinx_plot(p1.plot())
|
|
921
|
+
|
|
922
|
+
TESTS:
|
|
923
|
+
|
|
924
|
+
Every piecewise linear component of tropical polynomial function
|
|
925
|
+
has to have an integer slope::
|
|
926
|
+
|
|
927
|
+
sage: T = TropicalSemiring(QQ, use_min=False)
|
|
928
|
+
sage: R = PolynomialRing(T,'x')
|
|
929
|
+
sage: points = [(0,0),(2,3)]
|
|
930
|
+
sage: R.interpolation(points)
|
|
931
|
+
Traceback (most recent call last):
|
|
932
|
+
...
|
|
933
|
+
ValueError: the slope is not an integer
|
|
934
|
+
|
|
935
|
+
For max-plus algebra, the slope of the components has to be
|
|
936
|
+
increasing as we move from left to right. Conversely for min-plus
|
|
937
|
+
algebra, the slope of the components has to be decreasing from
|
|
938
|
+
left to right::
|
|
939
|
+
|
|
940
|
+
sage: T = TropicalSemiring(QQ, use_min=False)
|
|
941
|
+
sage: R = PolynomialRing(T,'x')
|
|
942
|
+
sage: points = [(-2,-3),(1,3),(2,4)]
|
|
943
|
+
sage: R.interpolation(points)
|
|
944
|
+
Traceback (most recent call last):
|
|
945
|
+
...
|
|
946
|
+
ValueError: can not interpolate these points
|
|
947
|
+
"""
|
|
948
|
+
points = sorted(points, key=lambda point: point[0])
|
|
949
|
+
all_slope = [0]
|
|
950
|
+
roots = {}
|
|
951
|
+
R = self.base()
|
|
952
|
+
if R._use_min:
|
|
953
|
+
point_order = range(len(points)-1, 0, -1)
|
|
954
|
+
else:
|
|
955
|
+
point_order = range(len(points)-1)
|
|
956
|
+
for i in point_order:
|
|
957
|
+
if R._use_min:
|
|
958
|
+
slope = (points[i-1][1]-points[i][1]) / (points[i-1][0]-points[i][0])
|
|
959
|
+
else:
|
|
960
|
+
slope = (points[i+1][1]-points[i][1]) / (points[i+1][0]-points[i][0])
|
|
961
|
+
if not slope.is_integer():
|
|
962
|
+
raise ValueError("the slope is not an integer")
|
|
963
|
+
if slope < all_slope[-1]:
|
|
964
|
+
raise ValueError("can not interpolate these points")
|
|
965
|
+
elif slope > all_slope[-1]:
|
|
966
|
+
order = slope - all_slope[-1]
|
|
967
|
+
all_slope.append(slope)
|
|
968
|
+
roots[points[i][0]] = order
|
|
969
|
+
|
|
970
|
+
if len(all_slope) == 1: # constant polynomial
|
|
971
|
+
return self(points[0][1])
|
|
972
|
+
|
|
973
|
+
result = self.one()
|
|
974
|
+
for root, order in roots.items():
|
|
975
|
+
result *= self([root, 0])**order
|
|
976
|
+
test_value = result(R(points[0][0]))
|
|
977
|
+
unit = R(points[0][1] - test_value.lift())
|
|
978
|
+
result *= unit
|
|
979
|
+
return result
|
|
980
|
+
|
|
981
|
+
@classmethod
|
|
982
|
+
def _implementation_names(cls, implementation, base_ring, sparse):
|
|
983
|
+
"""
|
|
984
|
+
Return the only implementation currently available for this semiring,
|
|
985
|
+
which is ``[None]``.
|
|
986
|
+
|
|
987
|
+
EXAMPLES::
|
|
988
|
+
|
|
989
|
+
sage: from sage.rings.semirings.tropical_polynomial import TropicalPolynomialSemiring
|
|
990
|
+
sage: T = TropicalSemiring(QQ)
|
|
991
|
+
sage: TropicalPolynomialSemiring._implementation_names(None, T, True)
|
|
992
|
+
[None]
|
|
993
|
+
"""
|
|
994
|
+
names = [None]
|
|
995
|
+
assert isinstance(names, list)
|
|
996
|
+
assert implementation in names
|
|
997
|
+
return names
|