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,3106 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-categories
|
|
2
|
+
r"""
|
|
3
|
+
Orthogonal polynomials
|
|
4
|
+
|
|
5
|
+
Chebyshev polynomials
|
|
6
|
+
---------------------
|
|
7
|
+
|
|
8
|
+
The Chebyshev polynomial of the first kind arises as a solution
|
|
9
|
+
to the differential equation
|
|
10
|
+
|
|
11
|
+
.. MATH::
|
|
12
|
+
|
|
13
|
+
(1-x^2)\,y'' - x\,y' + n^2\,y = 0
|
|
14
|
+
|
|
15
|
+
and those of the second kind as a solution to
|
|
16
|
+
|
|
17
|
+
.. MATH::
|
|
18
|
+
|
|
19
|
+
(1-x^2)\,y'' - 3x\,y' + n(n+2)\,y = 0.
|
|
20
|
+
|
|
21
|
+
The Chebyshev polynomials of the first kind are defined by the
|
|
22
|
+
recurrence relation
|
|
23
|
+
|
|
24
|
+
.. MATH::
|
|
25
|
+
|
|
26
|
+
T_0(x) = 1, \qquad T_1(x) = x, \qquad T_{n+1}(x) = 2xT_n(x) - T_{n-1}(x).
|
|
27
|
+
|
|
28
|
+
The Chebyshev polynomials of the second kind are defined by the
|
|
29
|
+
recurrence relation
|
|
30
|
+
|
|
31
|
+
.. MATH::
|
|
32
|
+
|
|
33
|
+
U_0(x) = 1, \qquad U_1(x) = 2x, \qquad U_{n+1}(x) = 2xU_n(x) - U_{n-1}(x).
|
|
34
|
+
|
|
35
|
+
For integers `m,n`, they satisfy the orthogonality relations
|
|
36
|
+
|
|
37
|
+
.. MATH::
|
|
38
|
+
|
|
39
|
+
\int_{-1}^1 T_n(x)T_m(x)\,\frac{dx}{\sqrt{1-x^2}} =
|
|
40
|
+
\left\{ \begin{array}{cl} 0 & \text{if } n\neq m, \\ \pi & \text{if } n=m=0, \\ \pi/2 & \text{if } n = m \neq 0, \end{array} \right.
|
|
41
|
+
|
|
42
|
+
and
|
|
43
|
+
|
|
44
|
+
.. MATH::
|
|
45
|
+
|
|
46
|
+
\int_{-1}^1 U_n(x)U_m(x)\sqrt{1-x^2}\,dx =\frac{\pi}{2}\delta_{m,n}.
|
|
47
|
+
|
|
48
|
+
They are named after Pafnuty Chebyshev (1821-1894, alternative
|
|
49
|
+
transliterations: Tchebyshef or Tschebyscheff).
|
|
50
|
+
|
|
51
|
+
Hermite polynomials
|
|
52
|
+
-------------------
|
|
53
|
+
|
|
54
|
+
The *Hermite polynomials* are defined either by
|
|
55
|
+
|
|
56
|
+
.. MATH::
|
|
57
|
+
|
|
58
|
+
H_n(x) = (-1)^n e^{x^2/2} \frac{d^n}{dx^n} e^{-x^2/2}
|
|
59
|
+
|
|
60
|
+
(the "probabilists' Hermite polynomials"), or by
|
|
61
|
+
|
|
62
|
+
.. MATH::
|
|
63
|
+
|
|
64
|
+
H_n(x) = (-1)^n e^{x^2}\frac{d^n}{dx^n}e^{-x^2}
|
|
65
|
+
|
|
66
|
+
(the "physicists' Hermite polynomials"). Sage (via Maxima) implements
|
|
67
|
+
the latter flavor. These satisfy the orthogonality relation
|
|
68
|
+
|
|
69
|
+
.. MATH::
|
|
70
|
+
|
|
71
|
+
\int_{-\infty}^{\infty} H_n(x) H_m(x) \, e^{-x^2} \, dx
|
|
72
|
+
= \sqrt{\pi} n! 2^n \delta_{nm}.
|
|
73
|
+
|
|
74
|
+
They are named in honor of Charles Hermite (1822-1901), but were first
|
|
75
|
+
introduced by Laplace in 1810 and also studied by Chebyshev in 1859.
|
|
76
|
+
|
|
77
|
+
Legendre polynomials
|
|
78
|
+
--------------------
|
|
79
|
+
|
|
80
|
+
Each *Legendre polynomial* `P_n(x)` is an `n`-th degree polynomial.
|
|
81
|
+
It may be expressed using Rodrigues' formula:
|
|
82
|
+
|
|
83
|
+
.. MATH::
|
|
84
|
+
|
|
85
|
+
P_n(x) = (2^n n!)^{-1} {\frac{d^n}{dx^n} } \left[ (x^2 -1)^n \right].
|
|
86
|
+
|
|
87
|
+
These are solutions to Legendre's differential equation:
|
|
88
|
+
|
|
89
|
+
.. MATH::
|
|
90
|
+
|
|
91
|
+
\frac{d}{dx} \left[ (1-x^2) {\frac{d}{dx}} P(x) \right] + n(n+1)P(x) = 0
|
|
92
|
+
|
|
93
|
+
and satisfy the orthogonality relation
|
|
94
|
+
|
|
95
|
+
.. MATH::
|
|
96
|
+
|
|
97
|
+
\int_{-1}^{1} P_m(x) P_n(x)\,dx = {\frac{2}{2n + 1}} \delta_{mn}.
|
|
98
|
+
|
|
99
|
+
The *Legendre function of the second kind* `Q_n(x)` is another
|
|
100
|
+
(linearly independent) solution to the Legendre differential equation.
|
|
101
|
+
It is not an "orthogonal polynomial" however.
|
|
102
|
+
|
|
103
|
+
The associated Legendre functions of the first kind `P_\ell^m(x)` can
|
|
104
|
+
be given in terms of the "usual" Legendre polynomials by
|
|
105
|
+
|
|
106
|
+
.. MATH::
|
|
107
|
+
|
|
108
|
+
\begin{aligned}
|
|
109
|
+
P_{\ell}^m(x) &= (-1)^m(1-x^2)^{m/2}\frac{d^m}{dx^m}P_\ell(x) \\
|
|
110
|
+
& = \frac{(-1)^m}{2^\ell \ell!} (1-x^2)^{m/2}\frac{d^{\ell+m}}{dx^{\ell+m}}(x^2-1)^{\ell}.
|
|
111
|
+
\end{aligned}
|
|
112
|
+
|
|
113
|
+
Assuming `0 \le m \le \ell`, they satisfy the orthogonality relation:
|
|
114
|
+
|
|
115
|
+
.. MATH::
|
|
116
|
+
|
|
117
|
+
\int_{-1}^{1} P_k^{(m)} P_{\ell}^{(m)} dx
|
|
118
|
+
= \frac{2(\ell+m)!}{(2\ell+1)(\ell-m)!}\ \delta _{k,\ell},
|
|
119
|
+
|
|
120
|
+
where `\delta _{k,\ell}` is the Kronecker delta.
|
|
121
|
+
|
|
122
|
+
The associated Legendre functions of the second kind
|
|
123
|
+
`Q_\ell^m(x)` can be given in terms of the "usual"
|
|
124
|
+
Legendre polynomials by
|
|
125
|
+
|
|
126
|
+
.. MATH::
|
|
127
|
+
|
|
128
|
+
Q_{\ell}^m(x) = (-1)^m (1-x^2)^{m/2} \frac{d^m}{dx^m} Q_{\ell}(x).
|
|
129
|
+
|
|
130
|
+
They are named after Adrien-Marie Legendre (1752-1833).
|
|
131
|
+
|
|
132
|
+
Laguerre polynomials
|
|
133
|
+
--------------------
|
|
134
|
+
|
|
135
|
+
*Laguerre polynomials* may be defined by the Rodrigues formula
|
|
136
|
+
|
|
137
|
+
.. MATH::
|
|
138
|
+
|
|
139
|
+
L_n(x) = \frac{e^x}{n!} \frac{d^n}{dx^n} \left( e^{-x} x^n \right).
|
|
140
|
+
|
|
141
|
+
They are solutions of Laguerre's equation:
|
|
142
|
+
|
|
143
|
+
.. MATH::
|
|
144
|
+
|
|
145
|
+
x\,y'' + (1 - x)\,y' + n\,y = 0
|
|
146
|
+
|
|
147
|
+
and satisfy the orthogonality relation
|
|
148
|
+
|
|
149
|
+
.. MATH::
|
|
150
|
+
|
|
151
|
+
\int_0^{\infty} L_m(x) L_n(x) e^{-x} \, dx = \delta_{mn}.
|
|
152
|
+
|
|
153
|
+
The generalized Laguerre polynomials may be defined by the Rodrigues formula:
|
|
154
|
+
|
|
155
|
+
.. MATH::
|
|
156
|
+
|
|
157
|
+
L_n^{(\alpha)}(x) = \frac{x^{-\alpha} e^x}{n!} \frac{d^n}{dx^n}
|
|
158
|
+
\left(e^{-x} x^{n+\alpha}\right).
|
|
159
|
+
|
|
160
|
+
(These are also sometimes called the associated Laguerre
|
|
161
|
+
polynomials.) The simple Laguerre polynomials are recovered from
|
|
162
|
+
the generalized polynomials by setting `\alpha = 0`.
|
|
163
|
+
|
|
164
|
+
They are named after Edmond Laguerre (1834-1886).
|
|
165
|
+
|
|
166
|
+
Jacobi polynomials
|
|
167
|
+
------------------
|
|
168
|
+
|
|
169
|
+
*Jacobi polynomials* are a class of orthogonal polynomials. They
|
|
170
|
+
are obtained from hypergeometric series in cases where the series
|
|
171
|
+
is in fact finite:
|
|
172
|
+
|
|
173
|
+
.. MATH::
|
|
174
|
+
|
|
175
|
+
P_n^{(\alpha,\beta)}(z) = \frac{(\alpha+1)_n}{n!}
|
|
176
|
+
\,_2F_1\left(-n,1+\alpha+\beta+n; \alpha+1; \frac{1-z}{2}\right),
|
|
177
|
+
|
|
178
|
+
where `()_n` is Pochhammer's symbol (for the rising factorial),
|
|
179
|
+
(Abramowitz and Stegun p561.) and thus have the explicit expression
|
|
180
|
+
|
|
181
|
+
.. MATH::
|
|
182
|
+
|
|
183
|
+
P_n^{(\alpha,\beta)} (z) = \frac{\Gamma(\alpha+n+1)}{n!\Gamma(\alpha+\beta+n+1)}
|
|
184
|
+
\sum_{m=0}^n \binom{n}{m} \frac{\Gamma(\alpha+\beta+n+m+1)}{\Gamma(\alpha+m+1)}
|
|
185
|
+
\left(\frac{z-1}{2}\right)^m.
|
|
186
|
+
|
|
187
|
+
They are named after Carl Gustav Jaboc Jacobi (1804-1851).
|
|
188
|
+
|
|
189
|
+
Gegenbauer polynomials
|
|
190
|
+
----------------------
|
|
191
|
+
|
|
192
|
+
*Ultraspherical* or *Gegenbauer polynomials* are given in terms of
|
|
193
|
+
the Jacobi polynomials `P_n^{(\alpha,\beta)}(x)` with
|
|
194
|
+
`\alpha = \beta = a - 1/2` by
|
|
195
|
+
|
|
196
|
+
.. MATH::
|
|
197
|
+
|
|
198
|
+
C_n^{(a)}(x) = \frac{\Gamma(a+1/2)}{\Gamma(2a)}
|
|
199
|
+
\frac{\Gamma(n+2a)}{\Gamma(n+a+1/2)} P_n^{(a-1/2,a-1/2)}(x).
|
|
200
|
+
|
|
201
|
+
They satisfy the orthogonality relation
|
|
202
|
+
|
|
203
|
+
.. MATH::
|
|
204
|
+
|
|
205
|
+
\int_{-1}^1(1-x^2)^{a-1/2}C_m^{(a)}(x)C_n^{(a)}(x)\, dx
|
|
206
|
+
= \delta_{mn}2^{1-2a}\pi \frac{\Gamma(n+2a)}{(n+a)\Gamma^2(a)\Gamma(n+1)},
|
|
207
|
+
|
|
208
|
+
for `a > -1/2`. They are obtained from hypergeometric series
|
|
209
|
+
in cases where the series is in fact finite:
|
|
210
|
+
|
|
211
|
+
.. MATH::
|
|
212
|
+
|
|
213
|
+
C_n^{(a)}(z) = \frac{(2a)^{\underline{n}}}{n!}
|
|
214
|
+
\,_2F_1\left(-n,2a+n; a+\frac{1}{2}; \frac{1-z}{2}\right)
|
|
215
|
+
|
|
216
|
+
where `\underline{n}` is the falling factorial. (See
|
|
217
|
+
Abramowitz and Stegun p561.)
|
|
218
|
+
|
|
219
|
+
They are named for Leopold Gegenbauer (1849-1903).
|
|
220
|
+
|
|
221
|
+
Krawtchouk polynomials
|
|
222
|
+
----------------------
|
|
223
|
+
|
|
224
|
+
The *Krawtchouk polynomials* are discrete orthogonal polynomials that
|
|
225
|
+
are given by the hypergeometric series
|
|
226
|
+
|
|
227
|
+
.. MATH::
|
|
228
|
+
|
|
229
|
+
K_j(x; n, p) = (-1)^j \binom{n}{j} p^j
|
|
230
|
+
\,_{2}F_1\left(-j,-x; -n; p^{-1}\right).
|
|
231
|
+
|
|
232
|
+
Since they are discrete orthogonal polynomials, they satisfy an orthogonality
|
|
233
|
+
relation defined on a discrete (in this case finite) set of points:
|
|
234
|
+
|
|
235
|
+
.. MATH::
|
|
236
|
+
|
|
237
|
+
\sum_{m=0}^n K_i(m; n, p) K_j(m; n, p) \, \binom{n}{m} p^m q^{n-m}
|
|
238
|
+
= \binom{n}{j} (pq)^j \delta_{ij},
|
|
239
|
+
|
|
240
|
+
where `q = 1 - p`. They can also be described by the recurrence relation
|
|
241
|
+
|
|
242
|
+
.. MATH::
|
|
243
|
+
|
|
244
|
+
j K_j(x; n, p) = (x - (n-j+1) p - (j-1) q) K_{j-1}(x; n, p)
|
|
245
|
+
- p q (n - j + 2) K_{j-2}(x; n, p),
|
|
246
|
+
|
|
247
|
+
where `K_0(x; n, p) = 1` and `K_1(x; n, p) = x - n p`.
|
|
248
|
+
|
|
249
|
+
They are named for Mykhailo Krawtchouk (1892-1942).
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
Meixner polynomials
|
|
253
|
+
-------------------
|
|
254
|
+
|
|
255
|
+
The *Meixner polynomials* are discrete orthogonal polynomials that
|
|
256
|
+
are given by the hypergeometric series
|
|
257
|
+
|
|
258
|
+
.. MATH::
|
|
259
|
+
|
|
260
|
+
M_n(x; n, p) = (-1)^j \binom{n}{j} p^j
|
|
261
|
+
\,_{2}F_1\left(-j,-x; -n; p^{-1}\right).
|
|
262
|
+
|
|
263
|
+
They satisfy an orthogonality relation:
|
|
264
|
+
|
|
265
|
+
.. MATH::
|
|
266
|
+
|
|
267
|
+
\sum_{k=0}^{\infty} \tilde{M}_n(k; b, c) \tilde{M}_m(k; b, c) \, \frac{(b)_k}{k!} c^k
|
|
268
|
+
= \frac{c^{-n} n!}{(b)_n (1-c)^b} \delta_{mn},
|
|
269
|
+
|
|
270
|
+
where `\tilde{M}_n(x; b, c) = M_n(x; b, c) / (b)_x`, for `b > 0 ` and
|
|
271
|
+
`0 < c < 1`. They can also be described by the recurrence relation
|
|
272
|
+
|
|
273
|
+
.. MATH::
|
|
274
|
+
|
|
275
|
+
\begin{aligned}
|
|
276
|
+
c (n-1+b) M_n(x; b, c) & = ((c-1) x + n-1 + c (n-1+b)) (b+n-1) M_{n-1}(x; b, c)
|
|
277
|
+
\\ & \qquad - (b+n-1) (b+n-2) (n-1) M_{n-2}(x; b, c),
|
|
278
|
+
\end{aligned}
|
|
279
|
+
|
|
280
|
+
where `M_0(x; b, c) = 0` and `M_1(x; b, c) = (1 - c^{-1}) x + b`.
|
|
281
|
+
|
|
282
|
+
They are named for Josef Meixner (1908-1994).
|
|
283
|
+
|
|
284
|
+
Hahn polynomials
|
|
285
|
+
----------------
|
|
286
|
+
|
|
287
|
+
The *Hahn polynomials* are discrete orthogonal polynomials that
|
|
288
|
+
are given by the hypergeometric series
|
|
289
|
+
|
|
290
|
+
.. MATH::
|
|
291
|
+
|
|
292
|
+
Q_k(x; a, b, n) = \,_{3}F_2\left(-k,k+a+b+1,-x; a+1,-n; 1\right).
|
|
293
|
+
|
|
294
|
+
They satisfy an orthogonality relation:
|
|
295
|
+
|
|
296
|
+
.. MATH::
|
|
297
|
+
|
|
298
|
+
\sum_{k=0}^{n-1} Q_i(k; a, b, n) Q_j(k; a, b, n) \, \rho(k)
|
|
299
|
+
= \frac{\delta_{ij}}{\pi_i},
|
|
300
|
+
|
|
301
|
+
where
|
|
302
|
+
|
|
303
|
+
.. MATH::
|
|
304
|
+
|
|
305
|
+
\begin{aligned}
|
|
306
|
+
\rho(k) &= \binom{a+k}{k} \binom{b+n-k}{n-k},
|
|
307
|
+
\\
|
|
308
|
+
\pi_i &= \delta_{ij} \frac{(-1)^i i! (b+1)_i (i+a+b+1)_{n+1}}{n! (2i+a+b+1) (-n)_i (a+1)_i}.
|
|
309
|
+
\end{aligned}
|
|
310
|
+
|
|
311
|
+
They can also be described by the recurrence relation
|
|
312
|
+
|
|
313
|
+
.. MATH::
|
|
314
|
+
|
|
315
|
+
A Q_k(x; a,b,n) = (-x + A + C) Q_{k-1}(x; a,b,n) - C Q_{k-2}(x; a,b,n),
|
|
316
|
+
|
|
317
|
+
where `Q_0(x; a,b,n) = 1` and `Q_1(x; a,b,n) = 1 - \frac{a+b+2}{(a+1)n} x` and
|
|
318
|
+
|
|
319
|
+
.. MATH::
|
|
320
|
+
|
|
321
|
+
A = \frac{(k+a+b) (k+a) (n-k+1)}{(2k+a+b-1) (2k+a+b)},
|
|
322
|
+
\qquad
|
|
323
|
+
C = \frac{(k-1) (k+b-1) (k+a+b+n)}{(2k+a+b-2) (2k+a+b-1)}.
|
|
324
|
+
|
|
325
|
+
They are named for Wolfgang Hahn (1911-1998), although they were first
|
|
326
|
+
introduced by Chebyshev in 1875.
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
Pochhammer symbol
|
|
330
|
+
-----------------
|
|
331
|
+
|
|
332
|
+
For completeness, the *Pochhammer symbol*, introduced by Leo August
|
|
333
|
+
Pochhammer, `(x)_n`, is used in the theory of special
|
|
334
|
+
functions to represent the "rising factorial" or "upper factorial"
|
|
335
|
+
|
|
336
|
+
.. MATH::
|
|
337
|
+
|
|
338
|
+
(x)_n = x(x+1)(x+2) \cdots (x+n-1) = \frac{(x+n-1)!}{(x-1)!}.
|
|
339
|
+
|
|
340
|
+
On the other hand, the *falling factorial* or *lower factorial* is
|
|
341
|
+
|
|
342
|
+
.. MATH::
|
|
343
|
+
|
|
344
|
+
x^{\underline{n}} = \frac{x!}{(x-n)!},
|
|
345
|
+
|
|
346
|
+
in the notation of Ronald L. Graham, Donald E. Knuth and Oren Patashnik
|
|
347
|
+
in their book Concrete Mathematics.
|
|
348
|
+
|
|
349
|
+
.. TODO::
|
|
350
|
+
|
|
351
|
+
Implement Zernike polynomials.
|
|
352
|
+
:wikipedia:`Zernike_polynomials`
|
|
353
|
+
|
|
354
|
+
REFERENCES:
|
|
355
|
+
|
|
356
|
+
- [AS1964]_
|
|
357
|
+
- :wikipedia:`Chebyshev_polynomials`
|
|
358
|
+
- :wikipedia:`Legendre_polynomials`
|
|
359
|
+
- :wikipedia:`Hermite_polynomials`
|
|
360
|
+
- https://mathworld.wolfram.com/GegenbauerPolynomial.html
|
|
361
|
+
- :wikipedia:`Jacobi_polynomials`
|
|
362
|
+
- :wikipedia:`Laguerre_polynomials`
|
|
363
|
+
- :wikipedia:`Associated_Legendre_polynomials`
|
|
364
|
+
- :wikipedia:`Kravchuk_polynomials`
|
|
365
|
+
- :wikipedia:`Meixner_polynomials`
|
|
366
|
+
- :wikipedia:`Hahn_polynomials`
|
|
367
|
+
- Roelof Koekeok and René F. Swarttouw, :arxiv:`math/9602214`
|
|
368
|
+
- [Koe1999]_
|
|
369
|
+
|
|
370
|
+
AUTHORS:
|
|
371
|
+
|
|
372
|
+
- David Joyner (2006-06)
|
|
373
|
+
- Stefan Reiterer (2010-)
|
|
374
|
+
- Ralf Stephan (2015-)
|
|
375
|
+
|
|
376
|
+
The original module wrapped some of the orthogonal/special functions
|
|
377
|
+
in the Maxima package "orthopoly" and was written by Barton
|
|
378
|
+
Willis of the University of Nebraska at Kearney.
|
|
379
|
+
"""
|
|
380
|
+
# ****************************************************************************
|
|
381
|
+
# Copyright (C) 2006 William Stein <wstein@gmail.com>
|
|
382
|
+
# 2006 David Joyner <wdj@usna.edu>
|
|
383
|
+
# 2010 Stefan Reiterer <maldun.finsterschreck@gmail.com>
|
|
384
|
+
#
|
|
385
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
386
|
+
#
|
|
387
|
+
# This code is distributed in the hope that it will be useful,
|
|
388
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
389
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
390
|
+
# General Public License for more details.
|
|
391
|
+
#
|
|
392
|
+
# The full text of the GPL is available at:
|
|
393
|
+
#
|
|
394
|
+
# https://www.gnu.org/licenses/
|
|
395
|
+
# ****************************************************************************
|
|
396
|
+
|
|
397
|
+
import warnings
|
|
398
|
+
|
|
399
|
+
import sage.rings.abc
|
|
400
|
+
|
|
401
|
+
from sage.arith.misc import rising_factorial
|
|
402
|
+
from sage.misc.lazy_import import lazy_import
|
|
403
|
+
from sage.rings.integer_ring import ZZ
|
|
404
|
+
from sage.rings.rational_field import QQ
|
|
405
|
+
from sage.symbolic.function import BuiltinFunction, GinacFunction
|
|
406
|
+
from sage.structure.element import Expression, parent
|
|
407
|
+
|
|
408
|
+
lazy_import('sage.functions.other', ['factorial', 'binomial'])
|
|
409
|
+
|
|
410
|
+
lazy_import('sage.misc.latex', 'latex')
|
|
411
|
+
lazy_import('sage.rings.cc', 'CC')
|
|
412
|
+
lazy_import('sage.rings.polynomial.polynomial_ring_constructor', 'PolynomialRing')
|
|
413
|
+
lazy_import('sage.rings.real_mpfr', 'RR')
|
|
414
|
+
|
|
415
|
+
lazy_import('sage.symbolic.ring', 'SR')
|
|
416
|
+
lazy_import('sage.calculus.calculus', 'maxima', as_='_maxima')
|
|
417
|
+
|
|
418
|
+
lazy_import('sage.libs.mpmath.utils', 'call', as_='_mpmath_utils_call')
|
|
419
|
+
lazy_import('sage.libs.mpmath.all', 'chebyt', as_='_mpmath_chebyt')
|
|
420
|
+
lazy_import('sage.libs.mpmath.all', 'chebyu', as_='_mpmath_chebyu')
|
|
421
|
+
lazy_import('sage.libs.mpmath.all', 'laguerre', as_='_mpmath_laguerre')
|
|
422
|
+
lazy_import('sage.libs.mpmath.all', 'legenp', as_='_mpmath_legenp')
|
|
423
|
+
lazy_import('sage.libs.mpmath.all', 'legenq', as_='_mpmath_legenq')
|
|
424
|
+
|
|
425
|
+
lazy_import('scipy.special', 'eval_chebyu', as_='_scipy_chebyu')
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
class OrthogonalFunction(BuiltinFunction):
|
|
429
|
+
"""
|
|
430
|
+
Base class for orthogonal polynomials.
|
|
431
|
+
|
|
432
|
+
This class is an abstract base class for all orthogonal polynomials since
|
|
433
|
+
they share similar properties. The evaluation as a polynomial
|
|
434
|
+
is either done via maxima, or with pynac.
|
|
435
|
+
|
|
436
|
+
Convention: The first argument is always the order of the polynomial,
|
|
437
|
+
the others are other values or parameters where the polynomial is
|
|
438
|
+
evaluated.
|
|
439
|
+
"""
|
|
440
|
+
def __init__(self, name, nargs=2, latex_name=None, conversions=None):
|
|
441
|
+
"""
|
|
442
|
+
:class:`OrthogonalFunction` class needs the same input parameter as
|
|
443
|
+
its parent class.
|
|
444
|
+
|
|
445
|
+
EXAMPLES::
|
|
446
|
+
|
|
447
|
+
sage: from sage.functions.orthogonal_polys import OrthogonalFunction
|
|
448
|
+
sage: new = OrthogonalFunction('testo_P')
|
|
449
|
+
sage: new
|
|
450
|
+
testo_P
|
|
451
|
+
"""
|
|
452
|
+
self._maxima_name = None
|
|
453
|
+
if conversions:
|
|
454
|
+
try:
|
|
455
|
+
self._maxima_name = conversions['maxima']
|
|
456
|
+
except KeyError:
|
|
457
|
+
pass
|
|
458
|
+
super().__init__(name=name, nargs=nargs,
|
|
459
|
+
latex_name=latex_name,
|
|
460
|
+
conversions=conversions)
|
|
461
|
+
|
|
462
|
+
def eval_formula(self, *args):
|
|
463
|
+
"""
|
|
464
|
+
Evaluate this polynomial using an explicit formula.
|
|
465
|
+
|
|
466
|
+
EXAMPLES::
|
|
467
|
+
|
|
468
|
+
sage: from sage.functions.orthogonal_polys import OrthogonalFunction
|
|
469
|
+
sage: P = OrthogonalFunction('testo_P')
|
|
470
|
+
sage: P.eval_formula(1, 2.0)
|
|
471
|
+
Traceback (most recent call last):
|
|
472
|
+
...
|
|
473
|
+
NotImplementedError: no explicit calculation of values implemented
|
|
474
|
+
"""
|
|
475
|
+
raise NotImplementedError("no explicit calculation of values implemented")
|
|
476
|
+
|
|
477
|
+
def _eval_special_values_(self, *args):
|
|
478
|
+
"""
|
|
479
|
+
Evaluate the polynomial explicitly for special values.
|
|
480
|
+
|
|
481
|
+
EXAMPLES::
|
|
482
|
+
|
|
483
|
+
sage: var('n') # needs sage.symbolic
|
|
484
|
+
n
|
|
485
|
+
sage: chebyshev_T(n, -1) # needs sage.symbolic
|
|
486
|
+
(-1)^n
|
|
487
|
+
"""
|
|
488
|
+
raise ValueError("no special values known")
|
|
489
|
+
|
|
490
|
+
def _eval_(self, n, *args):
|
|
491
|
+
"""
|
|
492
|
+
The :meth:`_eval_()` method decides which evaluation suits best
|
|
493
|
+
for the given input, and returns a proper value.
|
|
494
|
+
|
|
495
|
+
EXAMPLES::
|
|
496
|
+
|
|
497
|
+
sage: var('n,x') # needs sage.symbolic
|
|
498
|
+
(n, x)
|
|
499
|
+
sage: chebyshev_T(5, x) # needs sage.symbolic
|
|
500
|
+
16*x^5 - 20*x^3 + 5*x
|
|
501
|
+
"""
|
|
502
|
+
return None
|
|
503
|
+
|
|
504
|
+
def __call__(self, *args, **kwds):
|
|
505
|
+
"""
|
|
506
|
+
This overrides the call method from SageObject to avoid
|
|
507
|
+
problems with coercions, since the _eval_ method is able to
|
|
508
|
+
handle more data types than symbolic functions would normally
|
|
509
|
+
allow.
|
|
510
|
+
|
|
511
|
+
Thus we have the distinction between algebraic objects (if n is an integer),
|
|
512
|
+
and else as symbolic function.
|
|
513
|
+
|
|
514
|
+
EXAMPLES::
|
|
515
|
+
|
|
516
|
+
sage: # needs sage.symbolic
|
|
517
|
+
sage: chebyshev_T(5, x)
|
|
518
|
+
16*x^5 - 20*x^3 + 5*x
|
|
519
|
+
sage: chebyshev_T(5, x, algorithm='pari') # needs sage.libs.pari
|
|
520
|
+
16*x^5 - 20*x^3 + 5*x
|
|
521
|
+
sage: chebyshev_T(5, x, algorithm='maxima')
|
|
522
|
+
16*x^5 - 20*x^3 + 5*x
|
|
523
|
+
sage: chebyshev_T(5, x, algorithm='recursive')
|
|
524
|
+
16*x^5 - 20*x^3 + 5*x
|
|
525
|
+
"""
|
|
526
|
+
algorithm = kwds.get('algorithm', None)
|
|
527
|
+
if algorithm == 'pari':
|
|
528
|
+
return self.eval_pari(*args, **kwds)
|
|
529
|
+
elif algorithm == 'recursive':
|
|
530
|
+
return self.eval_recursive(*args, **kwds)
|
|
531
|
+
elif algorithm == 'maxima':
|
|
532
|
+
kwds['hold'] = True
|
|
533
|
+
return _maxima(self._eval_(*args, **kwds))._sage_()
|
|
534
|
+
|
|
535
|
+
return super().__call__(*args, **kwds)
|
|
536
|
+
|
|
537
|
+
|
|
538
|
+
class ChebyshevFunction(OrthogonalFunction):
|
|
539
|
+
"""
|
|
540
|
+
Abstract base class for Chebyshev polynomials of the first and second kind.
|
|
541
|
+
|
|
542
|
+
EXAMPLES::
|
|
543
|
+
|
|
544
|
+
sage: chebyshev_T(3, x) # needs sage.symbolic
|
|
545
|
+
4*x^3 - 3*x
|
|
546
|
+
"""
|
|
547
|
+
def __call__(self, n, *args, **kwds):
|
|
548
|
+
"""
|
|
549
|
+
This overrides the call method from :class:`SageObject` to
|
|
550
|
+
avoid problems with coercions, since the ``_eval_`` method is
|
|
551
|
+
able to handle more data types than symbolic functions would
|
|
552
|
+
normally allow.
|
|
553
|
+
|
|
554
|
+
Thus we have the distinction between algebraic objects (if n is an integer),
|
|
555
|
+
and else as symbolic function.
|
|
556
|
+
|
|
557
|
+
EXAMPLES::
|
|
558
|
+
|
|
559
|
+
sage: x = polygen(QQ, 'x')
|
|
560
|
+
sage: K.<a> = NumberField(x^3 - x - 1) # needs sage.rings.number_field
|
|
561
|
+
sage: chebyshev_T(5, a) # needs sage.rings.number_field
|
|
562
|
+
16*a^2 + a - 4
|
|
563
|
+
sage: chebyshev_T(5, MatrixSpace(ZZ, 2)([1, 2, -4, 7])) # needs sage.modules
|
|
564
|
+
[-40799 44162]
|
|
565
|
+
[-88324 91687]
|
|
566
|
+
sage: R.<x> = QQ[]
|
|
567
|
+
sage: parent(chebyshev_T(5, x))
|
|
568
|
+
Univariate Polynomial Ring in x over Rational Field
|
|
569
|
+
sage: chebyshev_T(5, 2, hold=True) # needs sage.symbolic
|
|
570
|
+
chebyshev_T(5, 2)
|
|
571
|
+
sage: chebyshev_T(1, 2, 3)
|
|
572
|
+
Traceback (most recent call last):
|
|
573
|
+
...
|
|
574
|
+
TypeError: Symbolic function chebyshev_T takes exactly 2 arguments (3 given)
|
|
575
|
+
"""
|
|
576
|
+
# If n is an integer: consider the polynomial as an algebraic (not symbolic) object
|
|
577
|
+
if n in ZZ and not kwds.get('hold', False):
|
|
578
|
+
try:
|
|
579
|
+
return self._eval_(n, *args)
|
|
580
|
+
except Exception:
|
|
581
|
+
pass
|
|
582
|
+
|
|
583
|
+
return super().__call__(n, *args, **kwds)
|
|
584
|
+
|
|
585
|
+
def _eval_(self, n, x):
|
|
586
|
+
"""
|
|
587
|
+
The :meth:`_eval_()` method decides which evaluation suits best
|
|
588
|
+
for the given input, and returns a proper value.
|
|
589
|
+
|
|
590
|
+
EXAMPLES::
|
|
591
|
+
|
|
592
|
+
sage: # needs sage.symbolic
|
|
593
|
+
sage: var('n,x')
|
|
594
|
+
(n, x)
|
|
595
|
+
sage: chebyshev_T(5, x)
|
|
596
|
+
16*x^5 - 20*x^3 + 5*x
|
|
597
|
+
sage: chebyshev_T(64, x)
|
|
598
|
+
2*(2*(2*(2*(2*(2*x^2 - 1)^2 - 1)^2 - 1)^2 - 1)^2 - 1)^2 - 1
|
|
599
|
+
sage: chebyshev_T(n, -1)
|
|
600
|
+
(-1)^n
|
|
601
|
+
sage: chebyshev_T(-7, x)
|
|
602
|
+
64*x^7 - 112*x^5 + 56*x^3 - 7*x
|
|
603
|
+
sage: chebyshev_T(3/2, x)
|
|
604
|
+
chebyshev_T(3/2, x)
|
|
605
|
+
|
|
606
|
+
sage: R.<t> = QQ[]
|
|
607
|
+
sage: chebyshev_T(2, t)
|
|
608
|
+
2*t^2 - 1
|
|
609
|
+
sage: chebyshev_U(2, t)
|
|
610
|
+
4*t^2 - 1
|
|
611
|
+
sage: parent(chebyshev_T(4, RIF(5))) # needs sage.rings.real_interval_field
|
|
612
|
+
Real Interval Field with 53 bits of precision
|
|
613
|
+
sage: RR2 = RealField(5) # needs sage.rings.real_mpfr
|
|
614
|
+
sage: chebyshev_T(100000, RR2(2)) # needs sage.rings.real_mpfr
|
|
615
|
+
8.9e57180
|
|
616
|
+
sage: chebyshev_T(5, Qp(3)(2)) # needs sage.rings.padics
|
|
617
|
+
2 + 3^2 + 3^3 + 3^4 + 3^5 + O(3^20)
|
|
618
|
+
sage: chebyshev_T(100001/2, 2) # needs sage.symbolic
|
|
619
|
+
...chebyshev_T(100001/2, 2)
|
|
620
|
+
sage: chebyshev_U._eval_(1.5, Mod(8,9)) is None # needs mpmath
|
|
621
|
+
True
|
|
622
|
+
"""
|
|
623
|
+
# n is an integer => evaluate algebraically (as polynomial)
|
|
624
|
+
if n in ZZ:
|
|
625
|
+
n = ZZ(n)
|
|
626
|
+
# Expanded symbolic expression only for small values of n
|
|
627
|
+
if isinstance(x, Expression) and n.abs() < 32:
|
|
628
|
+
return self.eval_formula(n, x)
|
|
629
|
+
return self.eval_algebraic(n, x)
|
|
630
|
+
|
|
631
|
+
if isinstance(x, Expression) or isinstance(n, Expression):
|
|
632
|
+
# Check for known identities
|
|
633
|
+
try:
|
|
634
|
+
return self._eval_special_values_(n, x)
|
|
635
|
+
except ValueError:
|
|
636
|
+
# Don't evaluate => keep symbolic
|
|
637
|
+
return None
|
|
638
|
+
|
|
639
|
+
# n is not an integer and neither n nor x is symbolic.
|
|
640
|
+
# We assume n and x are real/complex and evaluate numerically
|
|
641
|
+
try:
|
|
642
|
+
import sage.libs.mpmath.all as mpmath
|
|
643
|
+
return self._evalf_(n, x)
|
|
644
|
+
except mpmath.NoConvergence:
|
|
645
|
+
warnings.warn("mpmath failed, keeping expression unevaluated",
|
|
646
|
+
RuntimeWarning)
|
|
647
|
+
return None
|
|
648
|
+
except Exception:
|
|
649
|
+
# Numerical evaluation failed => keep symbolic
|
|
650
|
+
return None
|
|
651
|
+
|
|
652
|
+
|
|
653
|
+
class Func_chebyshev_T(ChebyshevFunction):
|
|
654
|
+
"""
|
|
655
|
+
Chebyshev polynomials of the first kind.
|
|
656
|
+
|
|
657
|
+
REFERENCE:
|
|
658
|
+
|
|
659
|
+
- [AS1964]_ 22.5.31 page 778 and 6.1.22 page 256.
|
|
660
|
+
|
|
661
|
+
EXAMPLES::
|
|
662
|
+
|
|
663
|
+
sage: chebyshev_T(5, x) # needs sage.symbolic
|
|
664
|
+
16*x^5 - 20*x^3 + 5*x
|
|
665
|
+
sage: var('k') # needs sage.symbolic
|
|
666
|
+
k
|
|
667
|
+
sage: test = chebyshev_T(k, x); test # needs sage.symbolic
|
|
668
|
+
chebyshev_T(k, x)
|
|
669
|
+
"""
|
|
670
|
+
def __init__(self):
|
|
671
|
+
"""
|
|
672
|
+
Init method for the chebyshev polynomials of the first kind.
|
|
673
|
+
|
|
674
|
+
EXAMPLES::
|
|
675
|
+
|
|
676
|
+
sage: # needs sage.symbolic
|
|
677
|
+
sage: var('n, x')
|
|
678
|
+
(n, x)
|
|
679
|
+
sage: from sage.functions.orthogonal_polys import Func_chebyshev_T
|
|
680
|
+
sage: chebyshev_T2 = Func_chebyshev_T()
|
|
681
|
+
sage: chebyshev_T2(1, x)
|
|
682
|
+
x
|
|
683
|
+
sage: chebyshev_T(x, x)._sympy_() # needs sympy
|
|
684
|
+
chebyshevt(x, x)
|
|
685
|
+
sage: maxima(chebyshev_T(1, x, hold=True))
|
|
686
|
+
_SAGE_VAR_x
|
|
687
|
+
sage: maxima(chebyshev_T(n, chebyshev_T(n, x)))
|
|
688
|
+
chebyshev_t(_SAGE_VAR_n,chebyshev_t(_SAGE_VAR_n,_SAGE_VAR_x))
|
|
689
|
+
"""
|
|
690
|
+
ChebyshevFunction.__init__(self, 'chebyshev_T', nargs=2,
|
|
691
|
+
conversions=dict(maxima='chebyshev_t',
|
|
692
|
+
mathematica='ChebyshevT',
|
|
693
|
+
sympy='chebyshevt',
|
|
694
|
+
giac='tchebyshev1'))
|
|
695
|
+
|
|
696
|
+
def _latex_(self):
|
|
697
|
+
r"""
|
|
698
|
+
TESTS::
|
|
699
|
+
|
|
700
|
+
sage: latex(chebyshev_T)
|
|
701
|
+
T_n
|
|
702
|
+
"""
|
|
703
|
+
return r"T_n"
|
|
704
|
+
|
|
705
|
+
def _print_latex_(self, n, z):
|
|
706
|
+
r"""
|
|
707
|
+
TESTS::
|
|
708
|
+
|
|
709
|
+
sage: latex(chebyshev_T(3, x, hold=True)) # needs sage.symbolic
|
|
710
|
+
T_{3}\left(x\right)
|
|
711
|
+
"""
|
|
712
|
+
return r"T_{{{}}}\left({}\right)".format(latex(n), latex(z))
|
|
713
|
+
|
|
714
|
+
def _eval_special_values_(self, n, x):
|
|
715
|
+
"""
|
|
716
|
+
Values known for special values of x.
|
|
717
|
+
For details see [AS1964]_ 22.4 (p. 777)
|
|
718
|
+
|
|
719
|
+
EXAMPLES::
|
|
720
|
+
|
|
721
|
+
sage: # needs sage.symbolic
|
|
722
|
+
sage: var('n')
|
|
723
|
+
n
|
|
724
|
+
sage: chebyshev_T(n, 1)
|
|
725
|
+
1
|
|
726
|
+
sage: chebyshev_T(n, 0)
|
|
727
|
+
1/2*(-1)^(1/2*n)*((-1)^n + 1)
|
|
728
|
+
sage: chebyshev_T(n, -1)
|
|
729
|
+
(-1)^n
|
|
730
|
+
sage: chebyshev_T._eval_special_values_(3/2, x)
|
|
731
|
+
Traceback (most recent call last):
|
|
732
|
+
...
|
|
733
|
+
ValueError: no special value found
|
|
734
|
+
sage: chebyshev_T._eval_special_values_(n, 0.1)
|
|
735
|
+
Traceback (most recent call last):
|
|
736
|
+
...
|
|
737
|
+
ValueError: no special value found
|
|
738
|
+
"""
|
|
739
|
+
if x == 1:
|
|
740
|
+
return x
|
|
741
|
+
|
|
742
|
+
if x == -1:
|
|
743
|
+
return x**n
|
|
744
|
+
|
|
745
|
+
if x == 0:
|
|
746
|
+
return (1+(-1)**n)*(-1)**(n/2)/2
|
|
747
|
+
|
|
748
|
+
raise ValueError("no special value found")
|
|
749
|
+
|
|
750
|
+
def _evalf_(self, n, x, **kwds):
|
|
751
|
+
"""
|
|
752
|
+
Evaluates :class:`chebyshev_T` numerically with mpmath.
|
|
753
|
+
|
|
754
|
+
EXAMPLES::
|
|
755
|
+
|
|
756
|
+
sage: # needs sage.rings.real_mpfr
|
|
757
|
+
sage: chebyshev_T._evalf_(10, 3)
|
|
758
|
+
2.26195370000000e7
|
|
759
|
+
sage: chebyshev_T._evalf_(10, 3, parent=RealField(75))
|
|
760
|
+
2.261953700000000000000e7
|
|
761
|
+
sage: chebyshev_T._evalf_(10, I) # needs sage.symbolic
|
|
762
|
+
-3363.00000000000
|
|
763
|
+
sage: chebyshev_T._evalf_(5, 0.3)
|
|
764
|
+
0.998880000000000
|
|
765
|
+
sage: chebyshev_T(1/2, 0)
|
|
766
|
+
0.707106781186548
|
|
767
|
+
sage: chebyshev_T(1/2, 3/2)
|
|
768
|
+
1.11803398874989
|
|
769
|
+
sage: chebyshev_T._evalf_(1.5, Mod(8,9))
|
|
770
|
+
Traceback (most recent call last):
|
|
771
|
+
...
|
|
772
|
+
TypeError: cannot evaluate chebyshev_T with parent Ring of integers modulo 9
|
|
773
|
+
|
|
774
|
+
This simply evaluates using :class:`RealField` or :class:`ComplexField`::
|
|
775
|
+
|
|
776
|
+
sage: chebyshev_T(1234.5, RDF(2.1)) # needs sage.rings.real_mpfr
|
|
777
|
+
5.48174256255782e735
|
|
778
|
+
sage: chebyshev_T(1234.5, I) # needs sage.rings.real_mpfr sage.symbolic
|
|
779
|
+
-1.21629397684152e472 - 1.21629397684152e472*I
|
|
780
|
+
|
|
781
|
+
For large values of ``n``, mpmath fails (but the algebraic formula
|
|
782
|
+
still works)::
|
|
783
|
+
|
|
784
|
+
sage: chebyshev_T._evalf_(10^6, 0.1) # needs sage.rings.real_mpfr
|
|
785
|
+
Traceback (most recent call last):
|
|
786
|
+
...
|
|
787
|
+
NoConvergence: Hypergeometric series converges too slowly.
|
|
788
|
+
Try increasing maxterms.
|
|
789
|
+
sage: chebyshev_T(10^6, 0.1) # needs sage.rings.real_mpfr
|
|
790
|
+
0.636384327171504
|
|
791
|
+
"""
|
|
792
|
+
try:
|
|
793
|
+
real_parent = kwds['parent']
|
|
794
|
+
except KeyError:
|
|
795
|
+
real_parent = parent(x)
|
|
796
|
+
|
|
797
|
+
if not isinstance(real_parent, (sage.rings.abc.RealField, sage.rings.abc.ComplexField)):
|
|
798
|
+
# parent is not a real or complex field: figure out a good parent
|
|
799
|
+
if x in RR:
|
|
800
|
+
x = RR(x)
|
|
801
|
+
real_parent = RR
|
|
802
|
+
elif x in CC:
|
|
803
|
+
x = CC(x)
|
|
804
|
+
real_parent = CC
|
|
805
|
+
|
|
806
|
+
if not isinstance(real_parent, (sage.rings.abc.RealField, sage.rings.abc.ComplexField)):
|
|
807
|
+
raise TypeError("cannot evaluate chebyshev_T with parent {}".format(real_parent))
|
|
808
|
+
|
|
809
|
+
return _mpmath_utils_call(_mpmath_chebyt, n, x, parent=real_parent)
|
|
810
|
+
|
|
811
|
+
def eval_formula(self, n, x):
|
|
812
|
+
"""
|
|
813
|
+
Evaluate ``chebyshev_T`` using an explicit formula.
|
|
814
|
+
See [AS1964]_ 227 (p. 782) for details for the recursions.
|
|
815
|
+
See also [Koe1999]_ for fast evaluation techniques.
|
|
816
|
+
|
|
817
|
+
INPUT:
|
|
818
|
+
|
|
819
|
+
- ``n`` -- integer
|
|
820
|
+
|
|
821
|
+
- ``x`` -- a value to evaluate the polynomial at (this can be
|
|
822
|
+
any ring element)
|
|
823
|
+
|
|
824
|
+
EXAMPLES::
|
|
825
|
+
|
|
826
|
+
sage: # needs sage.symbolic
|
|
827
|
+
sage: chebyshev_T.eval_formula(-1, x)
|
|
828
|
+
x
|
|
829
|
+
sage: chebyshev_T.eval_formula(0, x)
|
|
830
|
+
1
|
|
831
|
+
sage: chebyshev_T.eval_formula(1, x)
|
|
832
|
+
x
|
|
833
|
+
sage: chebyshev_T.eval_formula(10, x)
|
|
834
|
+
512*x^10 - 1280*x^8 + 1120*x^6 - 400*x^4 + 50*x^2 - 1
|
|
835
|
+
sage: chebyshev_T.eval_algebraic(10, x).expand()
|
|
836
|
+
512*x^10 - 1280*x^8 + 1120*x^6 - 400*x^4 + 50*x^2 - 1
|
|
837
|
+
|
|
838
|
+
sage: chebyshev_T.eval_formula(2, 0.1) == chebyshev_T._evalf_(2, 0.1) # needs sage.rings.complex_double
|
|
839
|
+
True
|
|
840
|
+
"""
|
|
841
|
+
if n < 0:
|
|
842
|
+
return self.eval_formula(-n, x)
|
|
843
|
+
elif n == 0:
|
|
844
|
+
return parent(x).one()
|
|
845
|
+
|
|
846
|
+
res = parent(x).zero()
|
|
847
|
+
for j in range(n // 2 + 1):
|
|
848
|
+
f = factorial(n-1-j) / factorial(j) / factorial(n-2*j)
|
|
849
|
+
res += (-1)**j * (2*x)**(n-2*j) * f
|
|
850
|
+
res *= n/2
|
|
851
|
+
return res
|
|
852
|
+
|
|
853
|
+
def eval_algebraic(self, n, x):
|
|
854
|
+
"""
|
|
855
|
+
Evaluate :class:`chebyshev_T` as polynomial, using a recursive
|
|
856
|
+
formula.
|
|
857
|
+
|
|
858
|
+
INPUT:
|
|
859
|
+
|
|
860
|
+
- ``n`` -- integer
|
|
861
|
+
|
|
862
|
+
- ``x`` -- a value to evaluate the polynomial at (this can be
|
|
863
|
+
any ring element)
|
|
864
|
+
|
|
865
|
+
EXAMPLES::
|
|
866
|
+
|
|
867
|
+
sage: chebyshev_T.eval_algebraic(5, x) # needs sage.symbolic
|
|
868
|
+
2*(2*(2*x^2 - 1)*x - x)*(2*x^2 - 1) - x
|
|
869
|
+
sage: chebyshev_T(-7, x) - chebyshev_T(7, x) # needs sage.symbolic
|
|
870
|
+
0
|
|
871
|
+
sage: R.<t> = ZZ[]
|
|
872
|
+
sage: chebyshev_T.eval_algebraic(-1, t)
|
|
873
|
+
t
|
|
874
|
+
sage: chebyshev_T.eval_algebraic(0, t)
|
|
875
|
+
1
|
|
876
|
+
sage: chebyshev_T.eval_algebraic(1, t)
|
|
877
|
+
t
|
|
878
|
+
sage: chebyshev_T(7^100, 1/2)
|
|
879
|
+
1/2
|
|
880
|
+
sage: chebyshev_T(7^100, Mod(2,3))
|
|
881
|
+
2
|
|
882
|
+
sage: n = 97; x = RIF(pi/2/n) # needs sage.symbolic
|
|
883
|
+
sage: chebyshev_T(n, cos(x)).contains_zero() # needs sage.symbolic
|
|
884
|
+
True
|
|
885
|
+
|
|
886
|
+
sage: # needs sage.rings.padics
|
|
887
|
+
sage: R.<t> = Zp(2, 8, 'capped-abs')[]
|
|
888
|
+
sage: chebyshev_T(10^6 + 1, t)
|
|
889
|
+
(2^7 + O(2^8))*t^5 + O(2^8)*t^4 + (2^6 + O(2^8))*t^3 + O(2^8)*t^2
|
|
890
|
+
+ (1 + 2^6 + O(2^8))*t + O(2^8)
|
|
891
|
+
"""
|
|
892
|
+
if n == 0:
|
|
893
|
+
return parent(x).one()
|
|
894
|
+
if n < 0:
|
|
895
|
+
return self._eval_recursive_(-n, x)[0]
|
|
896
|
+
return self._eval_recursive_(n, x)[0]
|
|
897
|
+
|
|
898
|
+
def _eval_recursive_(self, n, x, both=False):
|
|
899
|
+
"""
|
|
900
|
+
If ``both=True``, compute ``(T(n,x), T(n-1,x))`` using a
|
|
901
|
+
recursive formula.
|
|
902
|
+
If ``both=False``, return instead a tuple ``(T(n,x), False)``.
|
|
903
|
+
|
|
904
|
+
EXAMPLES::
|
|
905
|
+
|
|
906
|
+
sage: chebyshev_T._eval_recursive_(5, x) # needs sage.symbolic
|
|
907
|
+
(2*(2*(2*x^2 - 1)*x - x)*(2*x^2 - 1) - x, False)
|
|
908
|
+
sage: chebyshev_T._eval_recursive_(5, x, True) # needs sage.symbolic
|
|
909
|
+
(2*(2*(2*x^2 - 1)*x - x)*(2*x^2 - 1) - x, 2*(2*x^2 - 1)^2 - 1)
|
|
910
|
+
"""
|
|
911
|
+
if n == 1:
|
|
912
|
+
return x, parent(x).one()
|
|
913
|
+
|
|
914
|
+
assert n >= 2
|
|
915
|
+
a, b = self._eval_recursive_((n+1)//2, x, both or n % 2)
|
|
916
|
+
if n % 2 == 0:
|
|
917
|
+
return 2*a*a - 1, both and 2*a*b - x
|
|
918
|
+
else:
|
|
919
|
+
return 2*a*b - x, both and 2*b*b - 1
|
|
920
|
+
|
|
921
|
+
def _eval_numpy_(self, n, x):
|
|
922
|
+
"""
|
|
923
|
+
Evaluate ``self`` using numpy.
|
|
924
|
+
|
|
925
|
+
EXAMPLES::
|
|
926
|
+
|
|
927
|
+
sage: # needs numpy scipy
|
|
928
|
+
sage: import numpy
|
|
929
|
+
sage: z = numpy.array([1,2])
|
|
930
|
+
sage: z2 = numpy.array([[1,2],[1,2]])
|
|
931
|
+
sage: z3 = numpy.array([1,2,3.])
|
|
932
|
+
sage: chebyshev_T(1,z)
|
|
933
|
+
array([1., 2.])
|
|
934
|
+
sage: chebyshev_T(1,z2)
|
|
935
|
+
array([[1., 2.],
|
|
936
|
+
[1., 2.]])
|
|
937
|
+
sage: chebyshev_T(1,z3)
|
|
938
|
+
array([1., 2., 3.])
|
|
939
|
+
sage: chebyshev_T(z,0.1)
|
|
940
|
+
array([ 0.1 , -0.98])
|
|
941
|
+
"""
|
|
942
|
+
from scipy.special import eval_chebyt
|
|
943
|
+
return eval_chebyt(n, x)
|
|
944
|
+
|
|
945
|
+
def _derivative_(self, n, x, diff_param):
|
|
946
|
+
"""
|
|
947
|
+
Return the derivative of :class:`chebyshev_T` in form of the Chebyshev
|
|
948
|
+
polynomial of the second kind :class:`chebyshev_U`.
|
|
949
|
+
|
|
950
|
+
EXAMPLES::
|
|
951
|
+
|
|
952
|
+
sage: # needs sage.symbolic
|
|
953
|
+
sage: var('k')
|
|
954
|
+
k
|
|
955
|
+
sage: derivative(chebyshev_T(k, x), x)
|
|
956
|
+
k*chebyshev_U(k - 1, x)
|
|
957
|
+
sage: derivative(chebyshev_T(3, x), x)
|
|
958
|
+
12*x^2 - 3
|
|
959
|
+
sage: derivative(chebyshev_T(k, x), k)
|
|
960
|
+
Traceback (most recent call last):
|
|
961
|
+
...
|
|
962
|
+
NotImplementedError: derivative w.r.t. to the index is not supported yet
|
|
963
|
+
"""
|
|
964
|
+
if diff_param == 0:
|
|
965
|
+
raise NotImplementedError("derivative w.r.t. to the index is not supported yet")
|
|
966
|
+
elif diff_param == 1:
|
|
967
|
+
return n*chebyshev_U(n-1, x)
|
|
968
|
+
raise ValueError("illegal differentiation parameter {}".format(diff_param))
|
|
969
|
+
|
|
970
|
+
|
|
971
|
+
chebyshev_T = Func_chebyshev_T()
|
|
972
|
+
|
|
973
|
+
|
|
974
|
+
class Func_chebyshev_U(ChebyshevFunction):
|
|
975
|
+
"""
|
|
976
|
+
Class for the Chebyshev polynomial of the second kind.
|
|
977
|
+
|
|
978
|
+
REFERENCE:
|
|
979
|
+
|
|
980
|
+
- [AS1964]_ 22.8.3 page 783 and 6.1.22 page 256.
|
|
981
|
+
|
|
982
|
+
EXAMPLES::
|
|
983
|
+
|
|
984
|
+
sage: R.<t> = QQ[]
|
|
985
|
+
sage: chebyshev_U(2, t)
|
|
986
|
+
4*t^2 - 1
|
|
987
|
+
sage: chebyshev_U(3, t)
|
|
988
|
+
8*t^3 - 4*t
|
|
989
|
+
"""
|
|
990
|
+
def __init__(self):
|
|
991
|
+
"""
|
|
992
|
+
Init method for the chebyshev polynomials of the second kind.
|
|
993
|
+
|
|
994
|
+
EXAMPLES::
|
|
995
|
+
|
|
996
|
+
sage: # needs sage.symbolic
|
|
997
|
+
sage: var('n, x')
|
|
998
|
+
(n, x)
|
|
999
|
+
sage: from sage.functions.orthogonal_polys import Func_chebyshev_U
|
|
1000
|
+
sage: chebyshev_U2 = Func_chebyshev_U()
|
|
1001
|
+
sage: chebyshev_U2(1, x)
|
|
1002
|
+
2*x
|
|
1003
|
+
sage: chebyshev_U(x, x)._sympy_() # needs sympy
|
|
1004
|
+
chebyshevu(x, x)
|
|
1005
|
+
sage: maxima(chebyshev_U(2,x, hold=True))
|
|
1006
|
+
3*(...-...(8*(1-_SAGE_VAR_x))/3)+(4*(1-_SAGE_VAR_x)^2)/3+1)
|
|
1007
|
+
sage: maxima(chebyshev_U(n,x, hold=True))
|
|
1008
|
+
chebyshev_u(_SAGE_VAR_n,_SAGE_VAR_x)
|
|
1009
|
+
"""
|
|
1010
|
+
ChebyshevFunction.__init__(self, 'chebyshev_U', nargs=2,
|
|
1011
|
+
conversions=dict(maxima='chebyshev_u',
|
|
1012
|
+
mathematica='ChebyshevU',
|
|
1013
|
+
sympy='chebyshevu',
|
|
1014
|
+
giac='tchebyshev2'))
|
|
1015
|
+
|
|
1016
|
+
def _latex_(self):
|
|
1017
|
+
r"""
|
|
1018
|
+
TESTS::
|
|
1019
|
+
|
|
1020
|
+
sage: latex(chebyshev_U)
|
|
1021
|
+
U_n
|
|
1022
|
+
"""
|
|
1023
|
+
return r"U_n"
|
|
1024
|
+
|
|
1025
|
+
def _print_latex_(self, n, z):
|
|
1026
|
+
r"""
|
|
1027
|
+
TESTS::
|
|
1028
|
+
|
|
1029
|
+
sage: latex(chebyshev_U(3, x, hold=True)) # needs sage.symbolic
|
|
1030
|
+
U_{3}\left(x\right)
|
|
1031
|
+
"""
|
|
1032
|
+
return r"U_{{{}}}\left({}\right)".format(latex(n), latex(z))
|
|
1033
|
+
|
|
1034
|
+
def eval_formula(self, n, x):
|
|
1035
|
+
"""
|
|
1036
|
+
Evaluate ``chebyshev_U`` using an explicit formula.
|
|
1037
|
+
|
|
1038
|
+
See [AS1964]_ 227 (p. 782) for details on the recursions.
|
|
1039
|
+
See also [Koe1999]_ for the recursion formulas.
|
|
1040
|
+
|
|
1041
|
+
INPUT:
|
|
1042
|
+
|
|
1043
|
+
- ``n`` -- integer
|
|
1044
|
+
|
|
1045
|
+
- ``x`` -- a value to evaluate the polynomial at (this can be
|
|
1046
|
+
any ring element)
|
|
1047
|
+
|
|
1048
|
+
EXAMPLES::
|
|
1049
|
+
|
|
1050
|
+
sage: # needs sage.symbolic
|
|
1051
|
+
sage: chebyshev_U.eval_formula(10, x)
|
|
1052
|
+
1024*x^10 - 2304*x^8 + 1792*x^6 - 560*x^4 + 60*x^2 - 1
|
|
1053
|
+
sage: chebyshev_U.eval_formula(-2, x)
|
|
1054
|
+
-1
|
|
1055
|
+
sage: chebyshev_U.eval_formula(-1, x)
|
|
1056
|
+
0
|
|
1057
|
+
sage: chebyshev_U.eval_formula(0, x)
|
|
1058
|
+
1
|
|
1059
|
+
sage: chebyshev_U.eval_formula(1, x)
|
|
1060
|
+
2*x
|
|
1061
|
+
sage: chebyshev_U.eval_formula(2, 0.1) == chebyshev_U._evalf_(2, 0.1)
|
|
1062
|
+
True
|
|
1063
|
+
"""
|
|
1064
|
+
if n < -1:
|
|
1065
|
+
return -self.eval_formula(-n-2, x)
|
|
1066
|
+
|
|
1067
|
+
res = parent(x).zero()
|
|
1068
|
+
for j in range(n // 2 + 1):
|
|
1069
|
+
f = binomial(n-j, j)
|
|
1070
|
+
res += (-1)**j * (2*x)**(n-2*j) * f
|
|
1071
|
+
return res
|
|
1072
|
+
|
|
1073
|
+
def eval_algebraic(self, n, x):
|
|
1074
|
+
"""
|
|
1075
|
+
Evaluate :class:`chebyshev_U` as polynomial, using a recursive
|
|
1076
|
+
formula.
|
|
1077
|
+
|
|
1078
|
+
INPUT:
|
|
1079
|
+
|
|
1080
|
+
- ``n`` -- integer
|
|
1081
|
+
|
|
1082
|
+
- ``x`` -- a value to evaluate the polynomial at (this can be
|
|
1083
|
+
any ring element)
|
|
1084
|
+
|
|
1085
|
+
EXAMPLES::
|
|
1086
|
+
|
|
1087
|
+
sage: chebyshev_U.eval_algebraic(5, x) # needs sage.symbolic
|
|
1088
|
+
-2*((2*x + 1)*(2*x - 1)*x - 4*(2*x^2 - 1)*x)*(2*x + 1)*(2*x - 1)
|
|
1089
|
+
sage: parent(chebyshev_U(3, Mod(8,9)))
|
|
1090
|
+
Ring of integers modulo 9
|
|
1091
|
+
sage: parent(chebyshev_U(3, Mod(1,9)))
|
|
1092
|
+
Ring of integers modulo 9
|
|
1093
|
+
sage: chebyshev_U(-3, x) + chebyshev_U(1, x) # needs sage.symbolic
|
|
1094
|
+
0
|
|
1095
|
+
sage: chebyshev_U(-1, Mod(5,8))
|
|
1096
|
+
0
|
|
1097
|
+
sage: parent(chebyshev_U(-1, Mod(5,8)))
|
|
1098
|
+
Ring of integers modulo 8
|
|
1099
|
+
sage: R.<t> = ZZ[]
|
|
1100
|
+
sage: chebyshev_U.eval_algebraic(-2, t)
|
|
1101
|
+
-1
|
|
1102
|
+
sage: chebyshev_U.eval_algebraic(-1, t)
|
|
1103
|
+
0
|
|
1104
|
+
sage: chebyshev_U.eval_algebraic(0, t)
|
|
1105
|
+
1
|
|
1106
|
+
sage: chebyshev_U.eval_algebraic(1, t)
|
|
1107
|
+
2*t
|
|
1108
|
+
sage: n = 97; x = RIF(pi/n) # needs sage.symbolic
|
|
1109
|
+
sage: chebyshev_U(n - 1, cos(x)).contains_zero() # needs sage.symbolic
|
|
1110
|
+
True
|
|
1111
|
+
|
|
1112
|
+
sage: # needs sage.rings.padics
|
|
1113
|
+
sage: R.<t> = Zp(2, 6, 'capped-abs')[]
|
|
1114
|
+
sage: chebyshev_U(10^6 + 1, t)
|
|
1115
|
+
(2 + O(2^6))*t + O(2^6)
|
|
1116
|
+
"""
|
|
1117
|
+
if n == -1:
|
|
1118
|
+
return parent(x).zero()
|
|
1119
|
+
if n < 0:
|
|
1120
|
+
return -self._eval_recursive_(-n-2, x)[0]
|
|
1121
|
+
return self._eval_recursive_(n, x)[0]
|
|
1122
|
+
|
|
1123
|
+
def _eval_recursive_(self, n, x, both=False):
|
|
1124
|
+
"""
|
|
1125
|
+
If ``both=True``, compute ``(U(n,x), U(n-1,x))`` using a
|
|
1126
|
+
recursive formula.
|
|
1127
|
+
If ``both=False``, return instead a tuple ``(U(n,x), False)``.
|
|
1128
|
+
|
|
1129
|
+
EXAMPLES::
|
|
1130
|
+
|
|
1131
|
+
sage: chebyshev_U._eval_recursive_(3, x) # needs sage.symbolic
|
|
1132
|
+
(4*((2*x + 1)*(2*x - 1) - 2*x^2)*x, False)
|
|
1133
|
+
sage: chebyshev_U._eval_recursive_(3, x, True) # needs sage.symbolic
|
|
1134
|
+
(4*((2*x + 1)*(2*x - 1) - 2*x^2)*x,
|
|
1135
|
+
((2*x + 1)*(2*x - 1) + 2*x)*((2*x + 1)*(2*x - 1) - 2*x))
|
|
1136
|
+
"""
|
|
1137
|
+
if n == 0:
|
|
1138
|
+
return parent(x).one(), 2*x
|
|
1139
|
+
|
|
1140
|
+
assert n >= 1
|
|
1141
|
+
a, b = self._eval_recursive_((n-1)//2, x, True)
|
|
1142
|
+
if n % 2 == 0:
|
|
1143
|
+
return (b+a)*(b-a), both and 2*b*(x*b-a)
|
|
1144
|
+
else:
|
|
1145
|
+
return 2*a*(b-x*a), both and (b+a)*(b-a)
|
|
1146
|
+
|
|
1147
|
+
def _evalf_(self, n, x, **kwds):
|
|
1148
|
+
"""
|
|
1149
|
+
Evaluate :class:`chebyshev_U` numerically with mpmath.
|
|
1150
|
+
|
|
1151
|
+
EXAMPLES::
|
|
1152
|
+
|
|
1153
|
+
sage: chebyshev_U(5, -4 + 3.*I) # needs sage.symbolic
|
|
1154
|
+
98280.0000000000 - 11310.0000000000*I
|
|
1155
|
+
sage: chebyshev_U(10, 3).n(75) # needs sage.symbolic
|
|
1156
|
+
4.661117900000000000000e7
|
|
1157
|
+
sage: chebyshev_U._evalf_(1.5, Mod(8,9)) # needs sage.rings.real_mpfr
|
|
1158
|
+
Traceback (most recent call last):
|
|
1159
|
+
...
|
|
1160
|
+
TypeError: cannot evaluate chebyshev_U with parent Ring of integers modulo 9
|
|
1161
|
+
"""
|
|
1162
|
+
try:
|
|
1163
|
+
real_parent = kwds['parent']
|
|
1164
|
+
except KeyError:
|
|
1165
|
+
real_parent = parent(x)
|
|
1166
|
+
|
|
1167
|
+
if not isinstance(real_parent, (sage.rings.abc.RealField, sage.rings.abc.ComplexField)):
|
|
1168
|
+
# parent is not a real or complex field: figure out a good parent
|
|
1169
|
+
if x in RR:
|
|
1170
|
+
x = RR(x)
|
|
1171
|
+
real_parent = RR
|
|
1172
|
+
elif x in CC:
|
|
1173
|
+
x = CC(x)
|
|
1174
|
+
real_parent = CC
|
|
1175
|
+
|
|
1176
|
+
if not isinstance(real_parent, (sage.rings.abc.RealField, sage.rings.abc.ComplexField)):
|
|
1177
|
+
raise TypeError("cannot evaluate chebyshev_U with parent {}".format(real_parent))
|
|
1178
|
+
|
|
1179
|
+
return _mpmath_utils_call(_mpmath_chebyu, n, x, parent=real_parent)
|
|
1180
|
+
|
|
1181
|
+
def _eval_special_values_(self, n, x):
|
|
1182
|
+
"""
|
|
1183
|
+
Values known for special values of x.
|
|
1184
|
+
See [AS1964]_ 22.4 (p.777).
|
|
1185
|
+
|
|
1186
|
+
EXAMPLES::
|
|
1187
|
+
|
|
1188
|
+
sage: # needs sage.symbolic
|
|
1189
|
+
sage: var('n')
|
|
1190
|
+
n
|
|
1191
|
+
sage: chebyshev_U(n, 1)
|
|
1192
|
+
n + 1
|
|
1193
|
+
sage: chebyshev_U(n, 0)
|
|
1194
|
+
1/2*(-1)^(1/2*n)*((-1)^n + 1)
|
|
1195
|
+
sage: chebyshev_U(n, -1)
|
|
1196
|
+
(-1)^n*(n + 1)
|
|
1197
|
+
sage: chebyshev_U._eval_special_values_(n, 2)
|
|
1198
|
+
Traceback (most recent call last):
|
|
1199
|
+
...
|
|
1200
|
+
ValueError: no special value found
|
|
1201
|
+
"""
|
|
1202
|
+
if x == 1:
|
|
1203
|
+
return x*(n+1)
|
|
1204
|
+
|
|
1205
|
+
if x == -1:
|
|
1206
|
+
return x**n*(n+1)
|
|
1207
|
+
|
|
1208
|
+
if x == 0:
|
|
1209
|
+
return (1+(-1)**n)*(-1)**(n/2)/2
|
|
1210
|
+
|
|
1211
|
+
raise ValueError("no special value found")
|
|
1212
|
+
|
|
1213
|
+
def _eval_numpy_(self, n, x):
|
|
1214
|
+
"""
|
|
1215
|
+
Evaluate ``self`` using numpy.
|
|
1216
|
+
|
|
1217
|
+
EXAMPLES::
|
|
1218
|
+
|
|
1219
|
+
sage: # needs numpy scipy
|
|
1220
|
+
sage: import numpy
|
|
1221
|
+
sage: z = numpy.array([1,2])
|
|
1222
|
+
sage: z2 = numpy.array([[1,2],[1,2]])
|
|
1223
|
+
sage: z3 = numpy.array([1,2,3.])
|
|
1224
|
+
sage: chebyshev_U(1,z)
|
|
1225
|
+
array([2., 4.])
|
|
1226
|
+
sage: chebyshev_U(1,z2)
|
|
1227
|
+
array([[2., 4.],
|
|
1228
|
+
[2., 4.]])
|
|
1229
|
+
sage: chebyshev_U(1,z3)
|
|
1230
|
+
array([2., 4., 6.])
|
|
1231
|
+
sage: chebyshev_U(z,0.1)
|
|
1232
|
+
array([ 0.2 , -0.96])
|
|
1233
|
+
"""
|
|
1234
|
+
return _scipy_chebyu(n, x)
|
|
1235
|
+
|
|
1236
|
+
def _derivative_(self, n, x, diff_param):
|
|
1237
|
+
"""
|
|
1238
|
+
Return the derivative of :class:`chebyshev_U` in form of the Chebyshev
|
|
1239
|
+
polynomials of the first and second kind.
|
|
1240
|
+
|
|
1241
|
+
EXAMPLES::
|
|
1242
|
+
|
|
1243
|
+
sage: # needs sage.symbolic
|
|
1244
|
+
sage: var('k')
|
|
1245
|
+
k
|
|
1246
|
+
sage: derivative(chebyshev_U(k,x), x)
|
|
1247
|
+
((k + 1)*chebyshev_T(k + 1, x) - x*chebyshev_U(k, x))/(x^2 - 1)
|
|
1248
|
+
sage: derivative(chebyshev_U(3,x), x)
|
|
1249
|
+
24*x^2 - 4
|
|
1250
|
+
sage: derivative(chebyshev_U(k,x), k)
|
|
1251
|
+
Traceback (most recent call last):
|
|
1252
|
+
...
|
|
1253
|
+
NotImplementedError: derivative w.r.t. to the index is not supported yet
|
|
1254
|
+
"""
|
|
1255
|
+
if diff_param == 0:
|
|
1256
|
+
raise NotImplementedError("derivative w.r.t. to the index is not supported yet")
|
|
1257
|
+
elif diff_param == 1:
|
|
1258
|
+
return ((n+1)*chebyshev_T(n+1, x) - x*chebyshev_U(n, x)) / (x*x-1)
|
|
1259
|
+
raise ValueError("illegal differentiation parameter {}".format(diff_param))
|
|
1260
|
+
|
|
1261
|
+
|
|
1262
|
+
chebyshev_U = Func_chebyshev_U()
|
|
1263
|
+
|
|
1264
|
+
|
|
1265
|
+
class Func_legendre_P(GinacFunction):
|
|
1266
|
+
r"""
|
|
1267
|
+
EXAMPLES::
|
|
1268
|
+
|
|
1269
|
+
sage: # needs sage.symbolic
|
|
1270
|
+
sage: legendre_P(4, 2.0)
|
|
1271
|
+
55.3750000000000
|
|
1272
|
+
sage: legendre_P(1, x)
|
|
1273
|
+
x
|
|
1274
|
+
sage: legendre_P(4, x + 1)
|
|
1275
|
+
35/8*(x + 1)^4 - 15/4*(x + 1)^2 + 3/8
|
|
1276
|
+
sage: legendre_P(1/2, I+1.)
|
|
1277
|
+
1.05338240025858 + 0.359890322109665*I
|
|
1278
|
+
sage: legendre_P(0, SR(1)).parent()
|
|
1279
|
+
Symbolic Ring
|
|
1280
|
+
|
|
1281
|
+
sage: legendre_P(0, 0) # needs sage.symbolic
|
|
1282
|
+
1
|
|
1283
|
+
sage: legendre_P(1, x) # needs sage.symbolic
|
|
1284
|
+
x
|
|
1285
|
+
|
|
1286
|
+
sage: # needs sage.symbolic
|
|
1287
|
+
sage: legendre_P(4, 2.)
|
|
1288
|
+
55.3750000000000
|
|
1289
|
+
sage: legendre_P(5.5, 1.00001)
|
|
1290
|
+
1.00017875754114
|
|
1291
|
+
sage: legendre_P(1/2, I + 1).n()
|
|
1292
|
+
1.05338240025858 + 0.359890322109665*I
|
|
1293
|
+
sage: legendre_P(1/2, I + 1).n(59)
|
|
1294
|
+
1.0533824002585801 + 0.35989032210966539*I
|
|
1295
|
+
sage: legendre_P(42, RR(12345678))
|
|
1296
|
+
2.66314881466753e309
|
|
1297
|
+
sage: legendre_P(42, Reals(20)(12345678))
|
|
1298
|
+
2.6632e309
|
|
1299
|
+
sage: legendre_P(201/2, 0).n()
|
|
1300
|
+
0.0561386178630179
|
|
1301
|
+
sage: legendre_P(201/2, 0).n(100)
|
|
1302
|
+
0.056138617863017877699963095883
|
|
1303
|
+
|
|
1304
|
+
sage: # needs sage.symbolic
|
|
1305
|
+
sage: R.<x> = QQ[]
|
|
1306
|
+
sage: legendre_P(4, x)
|
|
1307
|
+
35/8*x^4 - 15/4*x^2 + 3/8
|
|
1308
|
+
sage: legendre_P(10000, x).coefficient(x, 1)
|
|
1309
|
+
0
|
|
1310
|
+
sage: var('t,x')
|
|
1311
|
+
(t, x)
|
|
1312
|
+
sage: legendre_P(-5, t)
|
|
1313
|
+
35/8*t^4 - 15/4*t^2 + 3/8
|
|
1314
|
+
sage: legendre_P(4, x + 1)
|
|
1315
|
+
35/8*(x + 1)^4 - 15/4*(x + 1)^2 + 3/8
|
|
1316
|
+
sage: legendre_P(4, sqrt(2))
|
|
1317
|
+
83/8
|
|
1318
|
+
sage: legendre_P(4, I*e)
|
|
1319
|
+
35/8*e^4 + 15/4*e^2 + 3/8
|
|
1320
|
+
|
|
1321
|
+
sage: # needs sage.symbolic
|
|
1322
|
+
sage: n = var('n')
|
|
1323
|
+
sage: derivative(legendre_P(n,x), x)
|
|
1324
|
+
(n*x*legendre_P(n, x) - n*legendre_P(n - 1, x))/(x^2 - 1)
|
|
1325
|
+
sage: derivative(legendre_P(3,x), x)
|
|
1326
|
+
15/2*x^2 - 3/2
|
|
1327
|
+
sage: derivative(legendre_P(n,x), n)
|
|
1328
|
+
Traceback (most recent call last):
|
|
1329
|
+
...
|
|
1330
|
+
RuntimeError: derivative w.r.t. to the index is not supported yet
|
|
1331
|
+
|
|
1332
|
+
TESTS:
|
|
1333
|
+
|
|
1334
|
+
Verify that :issue:`33962` is fixed::
|
|
1335
|
+
|
|
1336
|
+
sage: [legendre_P(n, 0) for n in range(-10, 10)] # needs sage.symbolic
|
|
1337
|
+
[0, 35/128, 0, -5/16, 0, 3/8, 0, -1/2, 0, 1,
|
|
1338
|
+
1, 0, -1/2, 0, 3/8, 0, -5/16, 0, 35/128, 0]
|
|
1339
|
+
|
|
1340
|
+
Verify that :issue:`33963` is fixed::
|
|
1341
|
+
|
|
1342
|
+
sage: # needs sage.symbolic
|
|
1343
|
+
sage: n = var("n")
|
|
1344
|
+
sage: assume(n, "integer")
|
|
1345
|
+
sage: assume(n, "even")
|
|
1346
|
+
sage: legendre_P(n, 0)
|
|
1347
|
+
2^(-n + 2)*(-1)^(1/2*n)*gamma(n)/(n*gamma(1/2*n)^2)
|
|
1348
|
+
sage: forget()
|
|
1349
|
+
"""
|
|
1350
|
+
def __init__(self):
|
|
1351
|
+
r"""
|
|
1352
|
+
Init method for the Legendre polynomials of the first kind.
|
|
1353
|
+
|
|
1354
|
+
EXAMPLES::
|
|
1355
|
+
|
|
1356
|
+
sage: loads(dumps(legendre_P))
|
|
1357
|
+
legendre_P
|
|
1358
|
+
"""
|
|
1359
|
+
BuiltinFunction.__init__(self, 'legendre_P', nargs=2, latex_name=r"P",
|
|
1360
|
+
conversions={'maxima': 'legendre_p',
|
|
1361
|
+
'mathematica': 'LegendreP',
|
|
1362
|
+
'maple': 'LegendreP',
|
|
1363
|
+
'giac': 'legendre'})
|
|
1364
|
+
|
|
1365
|
+
|
|
1366
|
+
legendre_P = Func_legendre_P()
|
|
1367
|
+
|
|
1368
|
+
|
|
1369
|
+
class Func_legendre_Q(BuiltinFunction):
|
|
1370
|
+
def __init__(self):
|
|
1371
|
+
r"""
|
|
1372
|
+
EXAMPLES::
|
|
1373
|
+
|
|
1374
|
+
sage: loads(dumps(legendre_Q))
|
|
1375
|
+
legendre_Q
|
|
1376
|
+
sage: maxima(legendre_Q(20, x, hold=True))._sage_().coefficient(x, 10) # needs sage.symbolic
|
|
1377
|
+
-29113619535/131072*log(-(x + 1)/(x - 1))
|
|
1378
|
+
"""
|
|
1379
|
+
BuiltinFunction.__init__(self, "legendre_Q", nargs=2, latex_name=r"Q",
|
|
1380
|
+
conversions={'maxima': 'legendre_q',
|
|
1381
|
+
'mathematica': 'LegendreQ',
|
|
1382
|
+
'maple': 'LegendreQ'})
|
|
1383
|
+
|
|
1384
|
+
def _eval_(self, n, x, *args, **kwds):
|
|
1385
|
+
r"""
|
|
1386
|
+
Return an evaluation of this Legendre Q expression.
|
|
1387
|
+
|
|
1388
|
+
EXAMPLES::
|
|
1389
|
+
|
|
1390
|
+
sage: # needs sage.symbolic
|
|
1391
|
+
sage: legendre_Q(2,x)
|
|
1392
|
+
1/4*(3*x^2 - 1)*(log(x + 1) - log(-x + 1)) - 3/2*x
|
|
1393
|
+
sage: legendre_Q(5, 0)
|
|
1394
|
+
-8/15
|
|
1395
|
+
sage: legendre_Q(2, 2*x)
|
|
1396
|
+
1/4*(12*x^2 - 1)*(log(2*x + 1) - log(-2*x + 1)) - 3*x
|
|
1397
|
+
sage: legendre_Q(1/2, I+1.)
|
|
1398
|
+
-0.511424110789061 + 1.34356195297194*I
|
|
1399
|
+
sage: legendre_Q(-1, x)
|
|
1400
|
+
Infinity
|
|
1401
|
+
"""
|
|
1402
|
+
ret = self._eval_special_values_(n, x)
|
|
1403
|
+
if ret is not None:
|
|
1404
|
+
return ret
|
|
1405
|
+
if n in ZZ:
|
|
1406
|
+
if n < 0:
|
|
1407
|
+
from sage.rings.infinity import unsigned_infinity
|
|
1408
|
+
return SR(unsigned_infinity)
|
|
1409
|
+
return self.eval_formula(n, x)
|
|
1410
|
+
|
|
1411
|
+
def _eval_special_values_(self, n, x):
|
|
1412
|
+
"""
|
|
1413
|
+
Special values known.
|
|
1414
|
+
|
|
1415
|
+
EXAMPLES::
|
|
1416
|
+
|
|
1417
|
+
sage: # needs sage.symbolic
|
|
1418
|
+
sage: var('n')
|
|
1419
|
+
n
|
|
1420
|
+
sage: legendre_Q(n, 0)
|
|
1421
|
+
-1/2*sqrt(pi)*gamma(1/2*n + 1/2)*sin(1/2*pi*n)/gamma(1/2*n + 1)
|
|
1422
|
+
sage: legendre_Q(-1., 0.)
|
|
1423
|
+
+infinity
|
|
1424
|
+
sage: legendre_Q(-1/2, 2)
|
|
1425
|
+
elliptic_kc(3/2)
|
|
1426
|
+
"""
|
|
1427
|
+
if n == QQ(-1)/2:
|
|
1428
|
+
from sage.functions.special import elliptic_kc
|
|
1429
|
+
return elliptic_kc((x+1)/2)
|
|
1430
|
+
|
|
1431
|
+
if x == 1:
|
|
1432
|
+
from sage.rings.infinity import unsigned_infinity
|
|
1433
|
+
return SR(unsigned_infinity)
|
|
1434
|
+
|
|
1435
|
+
if x == -1:
|
|
1436
|
+
from sage.rings.infinity import unsigned_infinity
|
|
1437
|
+
return SR(unsigned_infinity)
|
|
1438
|
+
|
|
1439
|
+
if x == 0:
|
|
1440
|
+
from .gamma import gamma
|
|
1441
|
+
from .other import sqrt
|
|
1442
|
+
from .trig import sin
|
|
1443
|
+
try:
|
|
1444
|
+
gam = gamma((n+1)/2)/gamma(n/2 + 1)
|
|
1445
|
+
if gam.is_infinity():
|
|
1446
|
+
return gam
|
|
1447
|
+
return -(sqrt(SR.pi()))/2 * sin(SR.pi()/2*n) * gam
|
|
1448
|
+
except TypeError:
|
|
1449
|
+
pass
|
|
1450
|
+
|
|
1451
|
+
def _evalf_(self, n, x, parent=None, **kwds):
|
|
1452
|
+
"""
|
|
1453
|
+
Float evaluation of Legendre Q(n, x) function.
|
|
1454
|
+
|
|
1455
|
+
EXAMPLES::
|
|
1456
|
+
|
|
1457
|
+
sage: legendre_Q(4, 2.) # needs mpmath
|
|
1458
|
+
0.00116107583162041 - 86.9828465962674*I
|
|
1459
|
+
sage: legendre_Q(1/2, I+1.) # needs sage.symbolic
|
|
1460
|
+
-0.511424110789061 + 1.34356195297194*I
|
|
1461
|
+
sage: legendre_Q(1/2, I+1).n(59) # needs sage.symbolic
|
|
1462
|
+
-0.51142411078906080 + 1.3435619529719394*I
|
|
1463
|
+
"""
|
|
1464
|
+
ret = self._eval_special_values_(n, x)
|
|
1465
|
+
if ret is not None:
|
|
1466
|
+
return ret
|
|
1467
|
+
|
|
1468
|
+
return _mpmath_utils_call(_mpmath_legenq, n, 0, x, parent=parent)
|
|
1469
|
+
|
|
1470
|
+
def eval_recursive(self, n, arg, **kwds):
|
|
1471
|
+
"""
|
|
1472
|
+
Return expanded Legendre Q(n, arg) function expression.
|
|
1473
|
+
|
|
1474
|
+
EXAMPLES::
|
|
1475
|
+
|
|
1476
|
+
sage: legendre_Q.eval_recursive(2, x) # needs sage.symbolic
|
|
1477
|
+
3/4*x^2*(log(x + 1) - log(-x + 1)) - 3/2*x - 1/4*log(x + 1) + 1/4*log(-x + 1)
|
|
1478
|
+
sage: legendre_Q.eval_recursive(20, x).expand().coefficient(x, 10) # needs sage.symbolic
|
|
1479
|
+
-29113619535/131072*log(x + 1) + 29113619535/131072*log(-x + 1)
|
|
1480
|
+
"""
|
|
1481
|
+
from sage.functions.log import ln
|
|
1482
|
+
if n == 0:
|
|
1483
|
+
return (ln(1+arg)-ln(1-arg))/2
|
|
1484
|
+
elif n == 1:
|
|
1485
|
+
return arg/2*(ln(1+arg)-ln(1-arg))-1
|
|
1486
|
+
|
|
1487
|
+
x, l = PolynomialRing(QQ, 'x,l').gens()
|
|
1488
|
+
help1 = l / 2
|
|
1489
|
+
help2 = x / 2 * l - 1
|
|
1490
|
+
for j in range(1, n):
|
|
1491
|
+
help3 = (2 * j + 1) * x * help2 - j * help1
|
|
1492
|
+
help3 = help3 / (j + 1)
|
|
1493
|
+
help1 = help2
|
|
1494
|
+
help2 = help3
|
|
1495
|
+
|
|
1496
|
+
sum1 = sum(help3.monomial_coefficient(mon)*arg**(mon.exponents()[0][0])
|
|
1497
|
+
for mon in help3.monomials() if not l.divides(mon))
|
|
1498
|
+
sum2 = sum(help3.monomial_coefficient(mon)*arg**(mon.exponents()[0][0])*(ln(1+arg)-ln(1-arg))
|
|
1499
|
+
for mon in help3.monomials() if l.divides(mon))
|
|
1500
|
+
return sum1 + sum2
|
|
1501
|
+
|
|
1502
|
+
def eval_formula(self, n, arg, **kwds):
|
|
1503
|
+
"""
|
|
1504
|
+
Return expanded Legendre ``Q(n, arg)`` function expression.
|
|
1505
|
+
|
|
1506
|
+
REFERENCE:
|
|
1507
|
+
|
|
1508
|
+
- T. M. Dunster, Legendre and Related Functions, https://dlmf.nist.gov/14.7#E2
|
|
1509
|
+
|
|
1510
|
+
EXAMPLES::
|
|
1511
|
+
|
|
1512
|
+
sage: # needs sage.symbolic
|
|
1513
|
+
sage: legendre_Q.eval_formula(1, x)
|
|
1514
|
+
1/2*x*(log(x + 1) - log(-x + 1)) - 1
|
|
1515
|
+
sage: legendre_Q.eval_formula(2, x).expand().collect(log(1+x)).collect(log(1-x))
|
|
1516
|
+
1/4*(3*x^2 - 1)*log(x + 1) - 1/4*(3*x^2 - 1)*log(-x + 1) - 3/2*x
|
|
1517
|
+
sage: legendre_Q.eval_formula(20, x).coefficient(x, 10)
|
|
1518
|
+
-29113619535/131072*log(x + 1) + 29113619535/131072*log(-x + 1)
|
|
1519
|
+
sage: legendre_Q(0, 2)
|
|
1520
|
+
-1/2*I*pi + 1/2*log(3)
|
|
1521
|
+
|
|
1522
|
+
sage: legendre_Q(0, 2.) # needs mpmath
|
|
1523
|
+
0.549306144334055 - 1.57079632679490*I
|
|
1524
|
+
"""
|
|
1525
|
+
from sage.functions.log import ln
|
|
1526
|
+
if n == 0:
|
|
1527
|
+
return (ln(1+arg)-ln(1-arg))/2
|
|
1528
|
+
elif n == 1:
|
|
1529
|
+
return arg/2*(ln(1+arg)-ln(1-arg))-1
|
|
1530
|
+
|
|
1531
|
+
arg = SR(arg)
|
|
1532
|
+
return legendre_P(n, arg)*(ln(1+arg)-ln(1-arg))/2 - self._Wfunc(n, arg)
|
|
1533
|
+
|
|
1534
|
+
def _Wfunc(self, n, arg):
|
|
1535
|
+
"""
|
|
1536
|
+
Helper function for ``eval_formula()``.
|
|
1537
|
+
|
|
1538
|
+
EXAMPLES::
|
|
1539
|
+
|
|
1540
|
+
sage: legendre_Q._Wfunc(2, x) # needs sage.symbolic
|
|
1541
|
+
3/2*x
|
|
1542
|
+
sage: legendre_Q._Wfunc(7, x) # needs sage.symbolic
|
|
1543
|
+
429/16*x^6 - 275/8*x^4 + 849/80*x^2 - 16/35
|
|
1544
|
+
"""
|
|
1545
|
+
if n == 0:
|
|
1546
|
+
return 0
|
|
1547
|
+
if n == 1:
|
|
1548
|
+
return 1
|
|
1549
|
+
x = PolynomialRing(QQ, 'x').gen()
|
|
1550
|
+
help1 = 0
|
|
1551
|
+
help2 = 1
|
|
1552
|
+
for j in range(2, n + 1):
|
|
1553
|
+
help3 = (2 * j - 1) * x * help2 - (j - 1) * help1
|
|
1554
|
+
help3 = help3 / j
|
|
1555
|
+
help1 = help2
|
|
1556
|
+
help2 = help3
|
|
1557
|
+
|
|
1558
|
+
return sum(b * arg**a for a, b in enumerate(help3))
|
|
1559
|
+
|
|
1560
|
+
def _derivative_(self, n, x, *args, **kwds):
|
|
1561
|
+
"""
|
|
1562
|
+
Return the derivative of legendre_Q.
|
|
1563
|
+
|
|
1564
|
+
EXAMPLES::
|
|
1565
|
+
|
|
1566
|
+
sage: # needs sage.symbolic
|
|
1567
|
+
sage: n = var('n')
|
|
1568
|
+
sage: derivative(legendre_Q(n,x), x)
|
|
1569
|
+
(n*x*legendre_Q(n, x) - n*legendre_Q(n - 1, x))/(x^2 - 1)
|
|
1570
|
+
sage: ex1 = legendre_Q(5, x, hold=True).diff(x).expand().simplify_full()
|
|
1571
|
+
sage: ex2 = legendre_Q(5, x).diff(x).expand().simplify_full()
|
|
1572
|
+
sage: ex1.subs(x=7).n() == ex2.subs(x=7).n()
|
|
1573
|
+
True
|
|
1574
|
+
sage: derivative(legendre_Q(n, x), n)
|
|
1575
|
+
Traceback (most recent call last):
|
|
1576
|
+
...
|
|
1577
|
+
NotImplementedError: Derivative w.r.t. to the index is not supported.
|
|
1578
|
+
"""
|
|
1579
|
+
diff_param = kwds['diff_param']
|
|
1580
|
+
if diff_param == 0:
|
|
1581
|
+
raise NotImplementedError("Derivative w.r.t. to the index is not supported.")
|
|
1582
|
+
else:
|
|
1583
|
+
return (n*x*legendre_Q(n, x) - n*legendre_Q(n-1, x))/(x**2 - 1)
|
|
1584
|
+
|
|
1585
|
+
|
|
1586
|
+
legendre_Q = Func_legendre_Q()
|
|
1587
|
+
|
|
1588
|
+
|
|
1589
|
+
class Func_assoc_legendre_P(BuiltinFunction):
|
|
1590
|
+
r"""
|
|
1591
|
+
Return the Ferrers function `\mathtt{P}_n^m(x)` of first kind for
|
|
1592
|
+
`x \in (-1,1)` with general order `m` and general degree `n`.
|
|
1593
|
+
|
|
1594
|
+
Ferrers functions of first kind are one of two linearly independent
|
|
1595
|
+
solutions of the associated Legendre differential equation
|
|
1596
|
+
|
|
1597
|
+
.. MATH::
|
|
1598
|
+
|
|
1599
|
+
(1-x^2) \frac{\mathrm{d}^2 w}{\mathrm{d}x^2} -
|
|
1600
|
+
2x \frac{\mathrm{d} w}{\mathrm{d}x} +
|
|
1601
|
+
\left(n(n+1) - \frac{m^2}{1-x^2}\right) w = 0
|
|
1602
|
+
|
|
1603
|
+
on the interval `x \in (-1, 1)` and are usually denoted by
|
|
1604
|
+
`\mathtt{P}_n^m(x)`.
|
|
1605
|
+
|
|
1606
|
+
.. SEEALSO ::
|
|
1607
|
+
|
|
1608
|
+
The other linearly independent solution is called *Ferrers function of
|
|
1609
|
+
second kind* and denoted by `\mathtt{Q}_n^m(x)`,
|
|
1610
|
+
see :class:`Func_assoc_legendre_Q`.
|
|
1611
|
+
|
|
1612
|
+
.. WARNING::
|
|
1613
|
+
|
|
1614
|
+
Ferrers functions must be carefully distinguished from associated
|
|
1615
|
+
Legendre functions which are defined on `\CC \setminus (- \infty, 1]`
|
|
1616
|
+
and have not yet been implemented.
|
|
1617
|
+
|
|
1618
|
+
EXAMPLES:
|
|
1619
|
+
|
|
1620
|
+
We give the first Ferrers functions for nonnegative integers
|
|
1621
|
+
`n` and `m` in the interval `-1<x<1`::
|
|
1622
|
+
|
|
1623
|
+
sage: for n in range(4): # needs sage.symbolic
|
|
1624
|
+
....: for m in range(n+1):
|
|
1625
|
+
....: print(f"P_{n}^{m}({x}) = {gen_legendre_P(n, m, x)}")
|
|
1626
|
+
P_0^0(x) = 1
|
|
1627
|
+
P_1^0(x) = x
|
|
1628
|
+
P_1^1(x) = -sqrt(-x^2 + 1)
|
|
1629
|
+
P_2^0(x) = 3/2*x^2 - 1/2
|
|
1630
|
+
P_2^1(x) = -3*sqrt(-x^2 + 1)*x
|
|
1631
|
+
P_2^2(x) = -3*x^2 + 3
|
|
1632
|
+
P_3^0(x) = 5/2*x^3 - 3/2*x
|
|
1633
|
+
P_3^1(x) = -3/2*(5*x^2 - 1)*sqrt(-x^2 + 1)
|
|
1634
|
+
P_3^2(x) = -15*(x^2 - 1)*x
|
|
1635
|
+
P_3^3(x) = -15*(-x^2 + 1)^(3/2)
|
|
1636
|
+
|
|
1637
|
+
These expressions for nonnegative integers are computed by the
|
|
1638
|
+
Rodrigues-type given in :meth:`eval_gen_poly`. Negative values for `n` are
|
|
1639
|
+
obtained by the following identity:
|
|
1640
|
+
|
|
1641
|
+
.. MATH::
|
|
1642
|
+
|
|
1643
|
+
P^{m}_{-n}(x) = P^{m}_{n-1}(x).
|
|
1644
|
+
|
|
1645
|
+
For `n` being a nonnegative integer, negative values for `m` are
|
|
1646
|
+
obtained by
|
|
1647
|
+
|
|
1648
|
+
.. MATH::
|
|
1649
|
+
|
|
1650
|
+
P^{-|m|}_n(x) = (-1)^{|m|} \frac{(n-|m|)!}{(n+|m|)!} P_n^{|m|}(x),
|
|
1651
|
+
|
|
1652
|
+
where `|m| \leq n`.
|
|
1653
|
+
|
|
1654
|
+
Here are some specific values with negative integers::
|
|
1655
|
+
|
|
1656
|
+
sage: # needs sage.symbolic
|
|
1657
|
+
sage: gen_legendre_P(-2, -1, x)
|
|
1658
|
+
1/2*sqrt(-x^2 + 1)
|
|
1659
|
+
sage: gen_legendre_P(2, -2, x)
|
|
1660
|
+
-1/8*x^2 + 1/8
|
|
1661
|
+
sage: gen_legendre_P(3, -2, x)
|
|
1662
|
+
-1/8*(x^2 - 1)*x
|
|
1663
|
+
sage: gen_legendre_P(1, -2, x)
|
|
1664
|
+
0
|
|
1665
|
+
|
|
1666
|
+
Here are some other random values with floating numbers::
|
|
1667
|
+
|
|
1668
|
+
sage: # needs sage.symbolic
|
|
1669
|
+
sage: m = var('m'); assume(m, 'integer')
|
|
1670
|
+
sage: gen_legendre_P(m, m, .2)
|
|
1671
|
+
0.960000000000000^(1/2*m)*(-1)^m*factorial(2*m)/(2^m*factorial(m))
|
|
1672
|
+
sage: gen_legendre_P(.2, m, 0)
|
|
1673
|
+
sqrt(pi)*2^m/(gamma(-1/2*m + 1.10000000000000)*gamma(-1/2*m + 0.400000000000000))
|
|
1674
|
+
sage: gen_legendre_P(.2, .2, .2)
|
|
1675
|
+
0.757714892929573
|
|
1676
|
+
|
|
1677
|
+
TESTS:
|
|
1678
|
+
|
|
1679
|
+
Some consistency checks::
|
|
1680
|
+
|
|
1681
|
+
sage: gen_legendre_P(1, 1, x) # needs sage.symbolic
|
|
1682
|
+
-sqrt(-x^2 + 1)
|
|
1683
|
+
sage: gen_legendre_P.eval_gen_poly(1, 1, x) # needs sage.symbolic
|
|
1684
|
+
-sqrt(-x^2 + 1)
|
|
1685
|
+
sage: gen_legendre_P(1, 1, 0.5) # abs tol 1e-14 # needs mpmath
|
|
1686
|
+
-0.866025403784439
|
|
1687
|
+
sage: gen_legendre_P.eval_gen_poly(1, 1, 0.5) # abs tol 1e-14 # needs sage.rings.real_mpfr
|
|
1688
|
+
-0.866025403784439
|
|
1689
|
+
sage: gen_legendre_P._evalf_(1, 1, 0.5) # abs tol 1e-14 # needs mpmath
|
|
1690
|
+
-0.866025403784439
|
|
1691
|
+
sage: gen_legendre_P(2/3, 1, 0.) # abs tol 1e-14 # needs mpmath
|
|
1692
|
+
-0.773063511309286
|
|
1693
|
+
sage: gen_legendre_P._eval_special_values_(2/3, 1, 0.).n() # abs tol 1e-14 # needs sage.symbolic
|
|
1694
|
+
-0.773063511309286
|
|
1695
|
+
|
|
1696
|
+
REFERENCES:
|
|
1697
|
+
|
|
1698
|
+
- [DLMF-Legendre]_
|
|
1699
|
+
"""
|
|
1700
|
+
def __init__(self):
|
|
1701
|
+
r"""
|
|
1702
|
+
EXAMPLES::
|
|
1703
|
+
|
|
1704
|
+
sage: loads(dumps(gen_legendre_P))
|
|
1705
|
+
gen_legendre_P
|
|
1706
|
+
sage: maxima(gen_legendre_P(20, 6, x, hold=True))._sage_().expand().coefficient(x,10) # needs sage.symbolic
|
|
1707
|
+
2508866163428625/128
|
|
1708
|
+
|
|
1709
|
+
TESTS::
|
|
1710
|
+
|
|
1711
|
+
sage: fricas(gen_legendre_P(2, 1/2, x)) # optional - fricas, needs sage.symbolic
|
|
1712
|
+
1
|
|
1713
|
+
legendreP(2,-,x)
|
|
1714
|
+
2
|
|
1715
|
+
|
|
1716
|
+
sage: gen_legendre_P(3, 0, x) # needs sage.symbolic
|
|
1717
|
+
5/2*x^3 - 3/2*x
|
|
1718
|
+
sage: fricas.legendreP(3, x) # optional - fricas, needs sage.symbolic
|
|
1719
|
+
5 3 3
|
|
1720
|
+
- x - - x
|
|
1721
|
+
2 2
|
|
1722
|
+
"""
|
|
1723
|
+
BuiltinFunction.__init__(self, "gen_legendre_P", nargs=3,
|
|
1724
|
+
latex_name=r"\mathtt{P}",
|
|
1725
|
+
conversions={'maxima': 'assoc_legendre_p',
|
|
1726
|
+
'mathematica': 'LegendreP',
|
|
1727
|
+
'fricas': 'legendreP',
|
|
1728
|
+
'maple': 'LegendreP'})
|
|
1729
|
+
|
|
1730
|
+
def _eval_(self, n, m, x, *args, **kwds):
|
|
1731
|
+
r"""
|
|
1732
|
+
Return an evaluation of this Legendre P(n, m, x) expression.
|
|
1733
|
+
|
|
1734
|
+
EXAMPLES::
|
|
1735
|
+
|
|
1736
|
+
sage: gen_legendre_P(13/2, 2, 0) # needs sage.symbolic
|
|
1737
|
+
4*sqrt(pi)/(gamma(13/4)*gamma(-15/4))
|
|
1738
|
+
sage: gen_legendre_P(3, 2, x) # needs sage.symbolic
|
|
1739
|
+
-15*(x^2 - 1)*x
|
|
1740
|
+
"""
|
|
1741
|
+
ret = self._eval_special_values_(n, m, x)
|
|
1742
|
+
if ret is not None:
|
|
1743
|
+
return ret
|
|
1744
|
+
if n in ZZ and m in ZZ and (x in ZZ or not SR(x).is_numeric()):
|
|
1745
|
+
return self._eval_int_ord_deg_(n, m, x)
|
|
1746
|
+
|
|
1747
|
+
def _eval_special_values_(self, n, m, x):
|
|
1748
|
+
"""
|
|
1749
|
+
Special values known.
|
|
1750
|
+
|
|
1751
|
+
EXAMPLES:
|
|
1752
|
+
|
|
1753
|
+
Case `|m| > |n|` for integers::
|
|
1754
|
+
|
|
1755
|
+
sage: gen_legendre_P(2, 3, 4) # needs mpmath
|
|
1756
|
+
0
|
|
1757
|
+
|
|
1758
|
+
Case `x = 0`::
|
|
1759
|
+
|
|
1760
|
+
sage: # needs sage.symbolic
|
|
1761
|
+
sage: gen_legendre_P(13/2, 2, 0)
|
|
1762
|
+
4*sqrt(pi)/(gamma(13/4)*gamma(-15/4))
|
|
1763
|
+
sage: m, n = var('m,n')
|
|
1764
|
+
sage: gen_legendre_P(n, m, 0)
|
|
1765
|
+
sqrt(pi)*2^m/(gamma(-1/2*m + 1/2*n + 1)*gamma(-1/2*m - 1/2*n + 1/2))
|
|
1766
|
+
sage: gen_legendre_P(n, 3, 0)
|
|
1767
|
+
8*sqrt(pi)/(gamma(1/2*n - 1/2)*gamma(-1/2*n - 1))
|
|
1768
|
+
sage: gen_legendre_P(3, m, 0)
|
|
1769
|
+
sqrt(pi)*2^m/(gamma(-1/2*m + 5/2)*gamma(-1/2*m - 1))
|
|
1770
|
+
|
|
1771
|
+
Case `m = n` for integers::
|
|
1772
|
+
|
|
1773
|
+
sage: # needs sage.symbolic
|
|
1774
|
+
sage: m = var('m')
|
|
1775
|
+
sage: assume(m, 'integer')
|
|
1776
|
+
sage: gen_legendre_P(m, m, x)
|
|
1777
|
+
(-1)^m*(-x^2 + 1)^(1/2*m)*factorial(2*m)/(2^m*factorial(m))
|
|
1778
|
+
sage: gen_legendre_P(m, m, .2)
|
|
1779
|
+
0.960000000000000^(1/2*m)*(-1)^m*factorial(2*m)/(2^m*factorial(m))
|
|
1780
|
+
sage: gen_legendre_P(2, 2, x)
|
|
1781
|
+
-3*x^2 + 3
|
|
1782
|
+
|
|
1783
|
+
Case `n = 0`::
|
|
1784
|
+
|
|
1785
|
+
sage: gen_legendre_P(m, 0, x) # needs sage.symbolic
|
|
1786
|
+
legendre_P(m, x)
|
|
1787
|
+
sage: gen_legendre_P(2, 0, 4) == legendre_P(2, 4) # needs sage.symbolic
|
|
1788
|
+
True
|
|
1789
|
+
"""
|
|
1790
|
+
if m == 0:
|
|
1791
|
+
# https://dlmf.nist.gov/14.7#E1
|
|
1792
|
+
return legendre_P(n, x)
|
|
1793
|
+
if x == 0:
|
|
1794
|
+
from .gamma import gamma
|
|
1795
|
+
from .other import sqrt
|
|
1796
|
+
# https://dlmf.nist.gov/14.5#E1
|
|
1797
|
+
return 2**m*sqrt(SR.pi())/gamma(n/2-m/2+1)/gamma(QQ(1/2)-n/2-m/2)
|
|
1798
|
+
if m.is_integer() and n.is_integer():
|
|
1799
|
+
if abs(m) > abs(n):
|
|
1800
|
+
# https://dlmf.nist.gov/14.7#E10 and https://dlmf.nist.gov/14.9#E3
|
|
1801
|
+
# and https://dlmf.nist.gov/14.9#E5
|
|
1802
|
+
return ZZ.zero()
|
|
1803
|
+
if m == n:
|
|
1804
|
+
# http://dlmf.nist.gov/14.5.iv and https://dlmf.nist.gov/14.9#E3
|
|
1805
|
+
return (-1)**m*factorial(2*m)/(2**m*factorial(m)) * (1-x**2)**(m/2)
|
|
1806
|
+
|
|
1807
|
+
def _eval_int_ord_deg_(self, n, m, x):
|
|
1808
|
+
r"""
|
|
1809
|
+
Evaluate the Ferrers function `P(n, m, x)` for `m` and `n` being
|
|
1810
|
+
concrete integers.
|
|
1811
|
+
|
|
1812
|
+
TESTS::
|
|
1813
|
+
|
|
1814
|
+
sage: gen_legendre_P._eval_int_ord_deg_(-2, 1, x) # needs sage.symbolic
|
|
1815
|
+
-sqrt(-x^2 + 1)
|
|
1816
|
+
sage: gen_legendre_P._eval_int_ord_deg_(2, -1, x) # needs sage.symbolic
|
|
1817
|
+
1/2*sqrt(-x^2 + 1)*x
|
|
1818
|
+
sage: gen_legendre_P._eval_int_ord_deg_(-2, -1, x) # needs sage.symbolic
|
|
1819
|
+
1/2*sqrt(-x^2 + 1)
|
|
1820
|
+
"""
|
|
1821
|
+
# use connection formulas to fall back on nonnegative n and m:
|
|
1822
|
+
if n < 0:
|
|
1823
|
+
# https://dlmf.nist.gov/14.9#E5
|
|
1824
|
+
return self._eval_int_ord_deg_(-n-1, m, x)
|
|
1825
|
+
if m < 0:
|
|
1826
|
+
# https://dlmf.nist.gov/14.9#E3
|
|
1827
|
+
return (-1)**(-m)*factorial(n+m)/factorial(n-m) * self._eval_int_ord_deg_(n, -m, x)
|
|
1828
|
+
# apply Rodrigues formula:
|
|
1829
|
+
return self.eval_gen_poly(n, m, x)
|
|
1830
|
+
|
|
1831
|
+
def _evalf_(self, n, m, x, parent=None, **kwds):
|
|
1832
|
+
"""
|
|
1833
|
+
Float evaluation of Ferrers function P(n, m, x).
|
|
1834
|
+
|
|
1835
|
+
EXAMPLES::
|
|
1836
|
+
|
|
1837
|
+
sage: gen_legendre_P(10, 2, 3).n() # abs tol 1e-14 # needs sage.symbolic
|
|
1838
|
+
-7.19496360000000e8
|
|
1839
|
+
sage: gen_legendre_P(5/2, 2, 1. + I) # needs sage.symbolic
|
|
1840
|
+
14.3165258449040 - 12.7850496155152*I
|
|
1841
|
+
sage: gen_legendre_P(5/2, 2, ComplexField(70)(1+I)) # needs sage.rings.real_mpfr sage.symbolic
|
|
1842
|
+
14.316525844904028532 - 12.785049615515157033*I
|
|
1843
|
+
sage: gen_legendre_P(2/3, 1, 0.) # needs mpmath
|
|
1844
|
+
-0.773063511309286
|
|
1845
|
+
"""
|
|
1846
|
+
return _mpmath_utils_call(_mpmath_legenp, n, m, x, parent=parent)
|
|
1847
|
+
|
|
1848
|
+
def eval_gen_poly(self, n, m, arg, **kwds):
|
|
1849
|
+
r"""
|
|
1850
|
+
Return the Ferrers function of first kind `\mathtt{P}_n^m(x)` for
|
|
1851
|
+
integers `n > -1, m > -1` given by the following Rodrigues-type
|
|
1852
|
+
formula:
|
|
1853
|
+
|
|
1854
|
+
.. MATH::
|
|
1855
|
+
|
|
1856
|
+
\mathtt{P}_n^m(x) = (-1)^{m+n} \frac{(1-x^2)^{m/2}}{2^n n!}
|
|
1857
|
+
\frac{\mathrm{d}^{m+n}}{\mathrm{d}x^{m+n}} (1-x^2)^n.
|
|
1858
|
+
|
|
1859
|
+
INPUT:
|
|
1860
|
+
|
|
1861
|
+
- ``n`` -- integer degree
|
|
1862
|
+
- ``m`` -- integer order
|
|
1863
|
+
- ``x`` -- either an integer or a non-numerical symbolic expression
|
|
1864
|
+
|
|
1865
|
+
EXAMPLES::
|
|
1866
|
+
|
|
1867
|
+
sage: gen_legendre_P(7, 4, x) # needs sage.symbolic
|
|
1868
|
+
3465/2*(13*x^3 - 3*x)*(x^2 - 1)^2
|
|
1869
|
+
sage: gen_legendre_P(3, 1, sqrt(x)) # needs sage.symbolic
|
|
1870
|
+
-3/2*(5*x - 1)*sqrt(-x + 1)
|
|
1871
|
+
|
|
1872
|
+
REFERENCE:
|
|
1873
|
+
|
|
1874
|
+
- [DLMF-Legendre]_, Section 14.7 eq. 10 (https://dlmf.nist.gov/14.7#E10)
|
|
1875
|
+
"""
|
|
1876
|
+
if n < 0 or m < 0:
|
|
1877
|
+
return
|
|
1878
|
+
R = PolynomialRing(QQ, 'x')
|
|
1879
|
+
x = R.gen()
|
|
1880
|
+
p = (1-x**2)**ZZ(n)
|
|
1881
|
+
for _ in range(m + n):
|
|
1882
|
+
p = p.diff(x)
|
|
1883
|
+
ex1 = (1-arg**2)**(QQ(m)/2)/2**n/factorial(ZZ(n))
|
|
1884
|
+
ex2 = sum(b * arg**a for a, b in enumerate(p))
|
|
1885
|
+
return (-1)**(m+n)*ex1*ex2
|
|
1886
|
+
|
|
1887
|
+
from sage.misc.superseded import deprecated_function_alias
|
|
1888
|
+
eval_poly = deprecated_function_alias(25034, eval_gen_poly)
|
|
1889
|
+
|
|
1890
|
+
def _derivative_(self, n, m, x, *args, **kwds):
|
|
1891
|
+
"""
|
|
1892
|
+
Return the derivative of ``gen_legendre_P(n,m,x)``.
|
|
1893
|
+
|
|
1894
|
+
EXAMPLES::
|
|
1895
|
+
|
|
1896
|
+
sage: # needs sage.symbolic
|
|
1897
|
+
sage: m, n = var('m,n')
|
|
1898
|
+
sage: derivative(gen_legendre_P(n,m,x), x)
|
|
1899
|
+
-((n + 1)*x*gen_legendre_P(n, m, x)
|
|
1900
|
+
+ (m - n - 1)*gen_legendre_P(n + 1, m, x))/(x^2 - 1)
|
|
1901
|
+
sage: gen_legendre_P(3, 2, x, hold=True).diff(x).expand().simplify_full()
|
|
1902
|
+
-45*x^2 + 15
|
|
1903
|
+
sage: derivative(gen_legendre_P(n,m,x), n)
|
|
1904
|
+
Traceback (most recent call last):
|
|
1905
|
+
...
|
|
1906
|
+
NotImplementedError: Derivative w.r.t. to the index is not supported.
|
|
1907
|
+
"""
|
|
1908
|
+
diff_param = kwds['diff_param']
|
|
1909
|
+
if diff_param == 0:
|
|
1910
|
+
raise NotImplementedError("Derivative w.r.t. to the index is not supported.")
|
|
1911
|
+
else:
|
|
1912
|
+
# https://dlmf.nist.gov/14.10#E4
|
|
1913
|
+
return ((m-n-1)*gen_legendre_P(n+1, m, x) + (n+1)*x*gen_legendre_P(n, m, x))/(1 - x**2)
|
|
1914
|
+
|
|
1915
|
+
|
|
1916
|
+
gen_legendre_P = Func_assoc_legendre_P()
|
|
1917
|
+
|
|
1918
|
+
|
|
1919
|
+
class Func_assoc_legendre_Q(BuiltinFunction):
|
|
1920
|
+
def __init__(self):
|
|
1921
|
+
r"""
|
|
1922
|
+
EXAMPLES::
|
|
1923
|
+
|
|
1924
|
+
sage: loads(dumps(gen_legendre_Q))
|
|
1925
|
+
gen_legendre_Q
|
|
1926
|
+
sage: maxima(gen_legendre_Q(2, 1, 3, hold=True))._sage_().simplify_full() # needs sage.symbolic
|
|
1927
|
+
1/4*sqrt(2)*(36*pi - 36*I*log(2) + 25*I)
|
|
1928
|
+
"""
|
|
1929
|
+
BuiltinFunction.__init__(self, "gen_legendre_Q", nargs=3, latex_name=r"Q",
|
|
1930
|
+
conversions={'maxima': 'assoc_legendre_q',
|
|
1931
|
+
'mathematica': 'LegendreQ',
|
|
1932
|
+
'maple': 'LegendreQ'})
|
|
1933
|
+
|
|
1934
|
+
def _eval_(self, n, m, x, *args, **kwds):
|
|
1935
|
+
r"""
|
|
1936
|
+
Return an evaluation of this Legendre Q(n, m, x) expression.
|
|
1937
|
+
|
|
1938
|
+
EXAMPLES::
|
|
1939
|
+
|
|
1940
|
+
sage: gen_legendre_Q(2, 1, 3) # needs sage.symbolic
|
|
1941
|
+
-1/4*sqrt(-2)*(-36*I*pi + 36*log(2) - 25)
|
|
1942
|
+
"""
|
|
1943
|
+
ret = self._eval_special_values_(n, m, x)
|
|
1944
|
+
if ret is not None:
|
|
1945
|
+
return ret
|
|
1946
|
+
if (n in ZZ and m in ZZ
|
|
1947
|
+
and n >= 0 and m >= 0
|
|
1948
|
+
and (x in ZZ or not SR(x).is_numeric())):
|
|
1949
|
+
return self.eval_recursive(n, m, x)
|
|
1950
|
+
|
|
1951
|
+
def _eval_special_values_(self, n, m, x):
|
|
1952
|
+
"""
|
|
1953
|
+
Special values known.
|
|
1954
|
+
|
|
1955
|
+
EXAMPLES::
|
|
1956
|
+
|
|
1957
|
+
sage: n, m = var('n m') # needs sage.symbolic
|
|
1958
|
+
sage: gen_legendre_Q(n, m, 0) # needs sage.symbolic
|
|
1959
|
+
-sqrt(pi)*2^(m - 1)*gamma(1/2*m + 1/2*n + 1/2)*sin(1/2*pi*m + 1/2*pi*n)/gamma(-1/2*m + 1/2*n + 1)
|
|
1960
|
+
"""
|
|
1961
|
+
if m == 0:
|
|
1962
|
+
return legendre_Q(n, x)
|
|
1963
|
+
if x.is_zero():
|
|
1964
|
+
from .gamma import gamma
|
|
1965
|
+
from .other import sqrt
|
|
1966
|
+
from .trig import sin
|
|
1967
|
+
if m in QQ and n in QQ:
|
|
1968
|
+
return -(sqrt(SR.pi()))*sin(SR.pi()/2*(m+n))*gamma(QQ(m+n+1)/2)/gamma(QQ(n-m)/2 + 1)*2**(m-1)
|
|
1969
|
+
elif isinstance(n, Expression) or isinstance(m, Expression):
|
|
1970
|
+
return -(sqrt(SR.pi()))*sin(SR.pi()/2*(m+n))*gamma((m+n+1)/2)/gamma((n-m)/2 + 1)*2**(m-1)
|
|
1971
|
+
|
|
1972
|
+
def _evalf_(self, n, m, x, parent=None, **kwds):
|
|
1973
|
+
"""
|
|
1974
|
+
Float evaluation of Legendre Q(n, m, x) function.
|
|
1975
|
+
|
|
1976
|
+
EXAMPLES::
|
|
1977
|
+
|
|
1978
|
+
sage: gen_legendre_Q(2, 1, 3.) # needs mpmath
|
|
1979
|
+
-39.9859464434253 + 0.0165114736149193*I
|
|
1980
|
+
sage: gen_legendre_Q(2, 1, ComplexField(70)(3)) # needs sage.rings.real_mpfr
|
|
1981
|
+
-39.985946443425296223 + 0.016511473614919329585*I
|
|
1982
|
+
"""
|
|
1983
|
+
ret = self._eval_special_values_(n, m, x)
|
|
1984
|
+
if ret is not None:
|
|
1985
|
+
return ret
|
|
1986
|
+
|
|
1987
|
+
return _mpmath_utils_call(_mpmath_legenq, n, m, x, parent=parent)
|
|
1988
|
+
|
|
1989
|
+
def eval_recursive(self, n, m, x, **kwds):
|
|
1990
|
+
"""
|
|
1991
|
+
Return the associated Legendre Q(n, m, arg) function for integers `n > -1, m > -1`.
|
|
1992
|
+
|
|
1993
|
+
EXAMPLES::
|
|
1994
|
+
|
|
1995
|
+
sage: # needs sage.symbolic
|
|
1996
|
+
sage: gen_legendre_Q(3, 4, x)
|
|
1997
|
+
48/(x^2 - 1)^2
|
|
1998
|
+
sage: gen_legendre_Q(4, 5, x)
|
|
1999
|
+
-384/((x^2 - 1)^2*sqrt(-x^2 + 1))
|
|
2000
|
+
sage: gen_legendre_Q(0, 1, x)
|
|
2001
|
+
-1/sqrt(-x^2 + 1)
|
|
2002
|
+
sage: gen_legendre_Q(0, 2, x)
|
|
2003
|
+
-1/2*((x + 1)^2 - (x - 1)^2)/(x^2 - 1)
|
|
2004
|
+
sage: gen_legendre_Q(2, 2, x).subs(x=2).expand()
|
|
2005
|
+
9/2*I*pi - 9/2*log(3) + 14/3
|
|
2006
|
+
"""
|
|
2007
|
+
from sage.misc.functional import sqrt
|
|
2008
|
+
if m == n + 1 or n == 0:
|
|
2009
|
+
if m.mod(2).is_zero():
|
|
2010
|
+
denom = (1 - x**2)**(m/2)
|
|
2011
|
+
else:
|
|
2012
|
+
denom = sqrt(1 - x**2)*(1 - x**2)**((m-1)/2)
|
|
2013
|
+
if m == n + 1:
|
|
2014
|
+
return (-1)**m*(m-1).factorial()*2**n/denom
|
|
2015
|
+
else:
|
|
2016
|
+
return (-1)**m*(m-1).factorial()*((x+1)**m - (x-1)**m)/(2*denom)
|
|
2017
|
+
else:
|
|
2018
|
+
return ((n-m+1)*x*gen_legendre_Q(n, m-1, x)-(n+m-1)*gen_legendre_Q(n-1, m-1, x))/sqrt(1-x**2)
|
|
2019
|
+
|
|
2020
|
+
def _derivative_(self, n, m, x, *args, **kwds):
|
|
2021
|
+
"""
|
|
2022
|
+
Return the derivative of ``gen_legendre_Q(n,m,x)``.
|
|
2023
|
+
|
|
2024
|
+
EXAMPLES::
|
|
2025
|
+
|
|
2026
|
+
sage: # needs sage.symbolic
|
|
2027
|
+
sage: m, n = var('m,n')
|
|
2028
|
+
sage: derivative(gen_legendre_Q(n,m,x), x)
|
|
2029
|
+
-((n + 1)*x*gen_legendre_Q(n, m, x)
|
|
2030
|
+
+ (m - n - 1)*gen_legendre_Q(n + 1, m, x))/(x^2 - 1)
|
|
2031
|
+
sage: ex1 = gen_legendre_Q(3, 2, x, hold=True).diff(x).expand().simplify_full()
|
|
2032
|
+
sage: ex2 = gen_legendre_Q(3, 2, x).diff(x).expand().simplify_full()
|
|
2033
|
+
sage: ex1.subs(x=5).n() == ex2.subs(x=5).n()
|
|
2034
|
+
True
|
|
2035
|
+
sage: derivative(gen_legendre_Q(n,m,x), n)
|
|
2036
|
+
Traceback (most recent call last):
|
|
2037
|
+
...
|
|
2038
|
+
NotImplementedError: Derivative w.r.t. to the index is not supported.
|
|
2039
|
+
"""
|
|
2040
|
+
diff_param = kwds['diff_param']
|
|
2041
|
+
if diff_param == 0:
|
|
2042
|
+
raise NotImplementedError("Derivative w.r.t. to the index is not supported.")
|
|
2043
|
+
else:
|
|
2044
|
+
return ((n-m+1)*gen_legendre_Q(n+1, m, x) - (n+1)*x*gen_legendre_Q(n, m, x))/(x**2 - 1)
|
|
2045
|
+
|
|
2046
|
+
|
|
2047
|
+
gen_legendre_Q = Func_assoc_legendre_Q()
|
|
2048
|
+
|
|
2049
|
+
|
|
2050
|
+
class Func_hermite(GinacFunction):
|
|
2051
|
+
r"""
|
|
2052
|
+
Return the Hermite polynomial for integers `n > -1`.
|
|
2053
|
+
|
|
2054
|
+
REFERENCE:
|
|
2055
|
+
|
|
2056
|
+
- [AS1964]_ 22.5.40 and 22.5.41, page 779.
|
|
2057
|
+
|
|
2058
|
+
EXAMPLES::
|
|
2059
|
+
|
|
2060
|
+
sage: # needs sage.symbolic
|
|
2061
|
+
sage: x = PolynomialRing(QQ, 'x').gen()
|
|
2062
|
+
sage: hermite(2, x)
|
|
2063
|
+
4*x^2 - 2
|
|
2064
|
+
sage: hermite(3, x)
|
|
2065
|
+
8*x^3 - 12*x
|
|
2066
|
+
sage: hermite(3, 2)
|
|
2067
|
+
40
|
|
2068
|
+
sage: S.<y> = PolynomialRing(RR)
|
|
2069
|
+
sage: hermite(3, y)
|
|
2070
|
+
8.00000000000000*y^3 - 12.0000000000000*y
|
|
2071
|
+
sage: R.<x,y> = QQ[]
|
|
2072
|
+
sage: hermite(3, y^2)
|
|
2073
|
+
8*y^6 - 12*y^2
|
|
2074
|
+
sage: w = var('w')
|
|
2075
|
+
sage: hermite(3, 2*w)
|
|
2076
|
+
64*w^3 - 24*w
|
|
2077
|
+
sage: hermite(5, 3.1416)
|
|
2078
|
+
5208.69733891963
|
|
2079
|
+
sage: hermite(5, RealField(100)(pi))
|
|
2080
|
+
5208.6167627118104649470287166
|
|
2081
|
+
|
|
2082
|
+
Check that :issue:`17192` is fixed::
|
|
2083
|
+
|
|
2084
|
+
sage: # needs sage.symbolic
|
|
2085
|
+
sage: x = PolynomialRing(QQ, 'x').gen()
|
|
2086
|
+
sage: hermite(0, x)
|
|
2087
|
+
1
|
|
2088
|
+
sage: hermite(-1, x)
|
|
2089
|
+
Traceback (most recent call last):
|
|
2090
|
+
...
|
|
2091
|
+
RuntimeError: hermite_eval: The index n must be a nonnegative integer
|
|
2092
|
+
sage: hermite(-7, x)
|
|
2093
|
+
Traceback (most recent call last):
|
|
2094
|
+
...
|
|
2095
|
+
RuntimeError: hermite_eval: The index n must be a nonnegative integer
|
|
2096
|
+
sage: m, x = SR.var('m,x')
|
|
2097
|
+
sage: hermite(m, x).diff(m)
|
|
2098
|
+
Traceback (most recent call last):
|
|
2099
|
+
...
|
|
2100
|
+
RuntimeError: derivative w.r.t. to the index is not supported yet
|
|
2101
|
+
"""
|
|
2102
|
+
def __init__(self):
|
|
2103
|
+
r"""
|
|
2104
|
+
Init method for the Hermite polynomials.
|
|
2105
|
+
|
|
2106
|
+
EXAMPLES::
|
|
2107
|
+
|
|
2108
|
+
sage: loads(dumps(hermite))
|
|
2109
|
+
hermite
|
|
2110
|
+
sage: hermite(x, x)._sympy_() # needs sympy sage.symbolic
|
|
2111
|
+
hermite(x, x)
|
|
2112
|
+
|
|
2113
|
+
TESTS::
|
|
2114
|
+
|
|
2115
|
+
sage: fricas(hermite(x, 5)) # optional - fricas # needs sage.symbolic
|
|
2116
|
+
hermiteH(x,5)
|
|
2117
|
+
|
|
2118
|
+
sage: hermite(5, x) # needs sage.symbolic
|
|
2119
|
+
32*x^5 - 160*x^3 + 120*x
|
|
2120
|
+
sage: fricas.hermiteH(5, x) # optional - fricas # needs sage.symbolic
|
|
2121
|
+
5 3
|
|
2122
|
+
32 x - 160 x + 120 x
|
|
2123
|
+
"""
|
|
2124
|
+
GinacFunction.__init__(self, "hermite", nargs=2, latex_name=r"H",
|
|
2125
|
+
conversions={'maxima': 'hermite',
|
|
2126
|
+
'mathematica': 'HermiteH',
|
|
2127
|
+
'maple': 'HermiteH',
|
|
2128
|
+
'fricas': 'hermiteH',
|
|
2129
|
+
'sympy': 'hermite'}, preserved_arg=2)
|
|
2130
|
+
|
|
2131
|
+
|
|
2132
|
+
hermite = Func_hermite()
|
|
2133
|
+
|
|
2134
|
+
|
|
2135
|
+
class Func_jacobi_P(OrthogonalFunction):
|
|
2136
|
+
r"""
|
|
2137
|
+
Return the Jacobi polynomial `P_n^{(a,b)}(x)` for integers
|
|
2138
|
+
`n > -1` and a and b symbolic or `a > -1` and `b > -1`.
|
|
2139
|
+
|
|
2140
|
+
The Jacobi polynomials are actually defined for all `a` and `b`.
|
|
2141
|
+
However, the Jacobi polynomial weight `(1-x)^a(1+x)^b` is not
|
|
2142
|
+
integrable for `a \leq -1` or `b \leq -1`.
|
|
2143
|
+
|
|
2144
|
+
REFERENCE:
|
|
2145
|
+
|
|
2146
|
+
- Table on page 789 in [AS1964]_.
|
|
2147
|
+
|
|
2148
|
+
EXAMPLES::
|
|
2149
|
+
|
|
2150
|
+
sage: x = PolynomialRing(QQ, 'x').gen()
|
|
2151
|
+
sage: jacobi_P(2, 0, 0, x) # needs sage.libs.flint sage.symbolic
|
|
2152
|
+
3/2*x^2 - 1/2
|
|
2153
|
+
sage: jacobi_P(2, 1, 2, 1.2) # needs sage.libs.flint
|
|
2154
|
+
5.01000000000000
|
|
2155
|
+
"""
|
|
2156
|
+
def __init__(self):
|
|
2157
|
+
r"""
|
|
2158
|
+
Init method for the Jacobi polynomials.
|
|
2159
|
+
|
|
2160
|
+
EXAMPLES::
|
|
2161
|
+
|
|
2162
|
+
sage: n, a, b, x = SR.var('n,a,b,x') # needs sage.symbolic
|
|
2163
|
+
sage: loads(dumps(jacobi_P))
|
|
2164
|
+
jacobi_P
|
|
2165
|
+
sage: jacobi_P(n, a, b, x, hold=True)._sympy_() # needs sympy sage.symbolic
|
|
2166
|
+
jacobi(n, a, b, x)
|
|
2167
|
+
|
|
2168
|
+
TESTS::
|
|
2169
|
+
|
|
2170
|
+
sage: fricas(jacobi_P(1/2, 4, 1/3, x)) # optional - fricas, needs sage.symbolic
|
|
2171
|
+
1 1
|
|
2172
|
+
jacobiP(-,4,-,x)
|
|
2173
|
+
2 3
|
|
2174
|
+
|
|
2175
|
+
sage: jacobi_P(1, 2, 3, x) # needs sage.symbolic
|
|
2176
|
+
7/2*x - 1/2
|
|
2177
|
+
sage: fricas.jacobiP(1, 2, 3, x) # optional - fricas, needs sage.symbolic
|
|
2178
|
+
7 x - 1
|
|
2179
|
+
-------
|
|
2180
|
+
2
|
|
2181
|
+
"""
|
|
2182
|
+
OrthogonalFunction.__init__(self, "jacobi_P", nargs=4, latex_name=r"P",
|
|
2183
|
+
conversions={'maxima': 'jacobi_p',
|
|
2184
|
+
'mathematica': 'JacobiP',
|
|
2185
|
+
'maple': 'JacobiP',
|
|
2186
|
+
'fricas': 'jacobiP',
|
|
2187
|
+
'sympy': 'jacobi'})
|
|
2188
|
+
|
|
2189
|
+
def _eval_(self, n, a, b, x):
|
|
2190
|
+
"""
|
|
2191
|
+
EXAMPLES::
|
|
2192
|
+
|
|
2193
|
+
sage: # needs sage.symbolic
|
|
2194
|
+
sage: n, a, b, x = SR.var('n,a,b,x')
|
|
2195
|
+
sage: jacobi_P(1, n, n, n)
|
|
2196
|
+
(n + 1)*n
|
|
2197
|
+
sage: jacobi_P(2, n, n, n)
|
|
2198
|
+
1/4*(2*n - 1)*(n + 2)*(n + 1)^2
|
|
2199
|
+
sage: jacobi_P(1, n, n, x)
|
|
2200
|
+
(n + 1)*x
|
|
2201
|
+
sage: jacobi_P(3, 2, 1, x)
|
|
2202
|
+
21/2*x^3 + 7/2*x^2 - 7/2*x - 1/2
|
|
2203
|
+
sage: jacobi_P(1, a, b, x)
|
|
2204
|
+
1/2*a*x + 1/2*b*x + 1/2*a - 1/2*b + x
|
|
2205
|
+
|
|
2206
|
+
TESTS:
|
|
2207
|
+
|
|
2208
|
+
Check that :issue:`17192` is fixed::
|
|
2209
|
+
|
|
2210
|
+
sage: x = PolynomialRing(QQ, 'x').gen()
|
|
2211
|
+
sage: jacobi_P(0, 0, 0, x) # needs sage.libs.flint sage.symbolic
|
|
2212
|
+
1
|
|
2213
|
+
sage: jacobi_P(-1, 0, 0, x) # needs sage.libs.flint sage.symbolic
|
|
2214
|
+
1
|
|
2215
|
+
sage: jacobi_P(-1, 1, 1, x) # needs sage.libs.flint sage.symbolic
|
|
2216
|
+
Traceback (most recent call last):
|
|
2217
|
+
...
|
|
2218
|
+
ValueError: n must be greater than -1, got n = -1
|
|
2219
|
+
|
|
2220
|
+
sage: jacobi_P(-7, 0, 0, x) # needs sage.libs.flint sage.symbolic
|
|
2221
|
+
231/16*x^6 - 315/16*x^4 + 105/16*x^2 - 5/16
|
|
2222
|
+
sage: jacobi_P(-7, 0, 2, x) # needs sage.symbolic
|
|
2223
|
+
Traceback (most recent call last):
|
|
2224
|
+
...
|
|
2225
|
+
ValueError: n must be greater than -1, got n = -7
|
|
2226
|
+
"""
|
|
2227
|
+
if SR(a).is_trivial_zero() and SR(b).is_trivial_zero():
|
|
2228
|
+
return legendre_P(n, x)
|
|
2229
|
+
if SR(n).is_numeric() and not (n > -1):
|
|
2230
|
+
raise ValueError("n must be greater than -1, got n = {0}".format(n))
|
|
2231
|
+
if n not in ZZ:
|
|
2232
|
+
return
|
|
2233
|
+
from .gamma import gamma
|
|
2234
|
+
s = sum(binomial(n, m) * gamma(a+b+n+m+1) / gamma(a+m+1) * ((x-1)/2)**m for m in range(n+1))
|
|
2235
|
+
r = gamma(a+n+1) / factorial(n) / gamma(n+a+b+1) * s
|
|
2236
|
+
return r.to_gamma().gamma_normalize().normalize()
|
|
2237
|
+
|
|
2238
|
+
def _evalf_(self, n, a, b, x, **kwds):
|
|
2239
|
+
"""
|
|
2240
|
+
EXAMPLES::
|
|
2241
|
+
|
|
2242
|
+
sage: jacobi_P(2, 1, 2, 1.2) # needs sage.symbolic
|
|
2243
|
+
5.01000000000000
|
|
2244
|
+
sage: jacobi_P(2, 1, 2, 1.2, hold=True).n(20) # needs sage.symbolic
|
|
2245
|
+
5.0100
|
|
2246
|
+
sage: jacobi_P(2, 1, 2, pi + I, hold=True).n(100) # needs sage.symbolic
|
|
2247
|
+
41.103034125334442891187112674 + 31.486722862692829003857755524*I
|
|
2248
|
+
"""
|
|
2249
|
+
from sage.rings.complex_arb import ComplexBallField as CBF
|
|
2250
|
+
the_parent = kwds.get('parent', None)
|
|
2251
|
+
if the_parent is None:
|
|
2252
|
+
the_parent = parent(x)
|
|
2253
|
+
prec = the_parent.precision()
|
|
2254
|
+
BF = CBF(prec+5)
|
|
2255
|
+
ret = BF(x).jacobi_P(BF(n), BF(a), BF(b))
|
|
2256
|
+
return SR(ret)._eval_self(the_parent)
|
|
2257
|
+
|
|
2258
|
+
|
|
2259
|
+
jacobi_P = Func_jacobi_P()
|
|
2260
|
+
|
|
2261
|
+
|
|
2262
|
+
class Func_ultraspherical(GinacFunction):
|
|
2263
|
+
r"""
|
|
2264
|
+
Return the ultraspherical (or Gegenbauer) polynomial ``gegenbauer(n,a,x)``,
|
|
2265
|
+
|
|
2266
|
+
.. MATH::
|
|
2267
|
+
|
|
2268
|
+
C_n^{a}(x) = \sum_{k=0}^{\lfloor n/2\rfloor} (-1)^k
|
|
2269
|
+
\frac{\Gamma(n-k+a)}{\Gamma(a)k!(n-2k)!} (2x)^{n-2k}.
|
|
2270
|
+
|
|
2271
|
+
When `n` is a nonnegative integer, this formula gives a
|
|
2272
|
+
polynomial in `z` of degree `n`, but all parameters are
|
|
2273
|
+
permitted to be complex numbers. When `a = 1/2`, the
|
|
2274
|
+
Gegenbauer polynomial reduces to a Legendre polynomial.
|
|
2275
|
+
|
|
2276
|
+
Computed using Pynac.
|
|
2277
|
+
|
|
2278
|
+
For numerical evaluation, consider using the `mpmath library
|
|
2279
|
+
<http://mpmath.org/doc/current/functions/orthogonal.html#gegenbauer-polynomials>`_,
|
|
2280
|
+
as it also allows complex numbers (and negative `n` as well);
|
|
2281
|
+
see the examples below.
|
|
2282
|
+
|
|
2283
|
+
REFERENCE:
|
|
2284
|
+
|
|
2285
|
+
- [AS1964]_ 22.5.27
|
|
2286
|
+
|
|
2287
|
+
EXAMPLES::
|
|
2288
|
+
|
|
2289
|
+
sage: # needs sage.symbolic
|
|
2290
|
+
sage: ultraspherical(8, 101/11, x)
|
|
2291
|
+
795972057547264/214358881*x^8 - 62604543852032/19487171*x^6...
|
|
2292
|
+
sage: x = PolynomialRing(QQ, 'x').gen()
|
|
2293
|
+
sage: ultraspherical(2, 3/2, x)
|
|
2294
|
+
15/2*x^2 - 3/2
|
|
2295
|
+
sage: ultraspherical(1, 1, x)
|
|
2296
|
+
2*x
|
|
2297
|
+
sage: t = PolynomialRing(RationalField(), "t").gen()
|
|
2298
|
+
sage: gegenbauer(3, 2, t)
|
|
2299
|
+
32*t^3 - 12*t
|
|
2300
|
+
sage: x = SR.var('x')
|
|
2301
|
+
sage: n = ZZ.random_element(5, 5001)
|
|
2302
|
+
sage: a = QQ.random_element().abs() + 5
|
|
2303
|
+
sage: s = ( (n + 1)*ultraspherical(n + 1, a, x)
|
|
2304
|
+
....: - 2*x*(n + a)*ultraspherical(n, a, x)
|
|
2305
|
+
....: + (n + 2*a - 1)*ultraspherical(n - 1, a, x) )
|
|
2306
|
+
sage: s.expand().is_zero()
|
|
2307
|
+
True
|
|
2308
|
+
sage: ultraspherical(5, 9/10, 3.1416)
|
|
2309
|
+
6949.55439044240
|
|
2310
|
+
sage: ultraspherical(5, 9/10, RealField(100)(pi)) # needs sage.rings.real_mpfr
|
|
2311
|
+
6949.4695419382702451843080687
|
|
2312
|
+
|
|
2313
|
+
sage: # needs sage.symbolic
|
|
2314
|
+
sage: a, n = SR.var('a,n')
|
|
2315
|
+
sage: gegenbauer(2, a, x)
|
|
2316
|
+
2*(a + 1)*a*x^2 - a
|
|
2317
|
+
sage: gegenbauer(3, a, x)
|
|
2318
|
+
4/3*(a + 2)*(a + 1)*a*x^3 - 2*(a + 1)*a*x
|
|
2319
|
+
sage: gegenbauer(3, a, x).expand()
|
|
2320
|
+
4/3*a^3*x^3 + 4*a^2*x^3 + 8/3*a*x^3 - 2*a^2*x - 2*a*x
|
|
2321
|
+
sage: gegenbauer(10, a, x).expand().coefficient(x, 2)
|
|
2322
|
+
1/12*a^6 + 5/4*a^5 + 85/12*a^4 + 75/4*a^3 + 137/6*a^2 + 10*a
|
|
2323
|
+
sage: ex = gegenbauer(100, a, x)
|
|
2324
|
+
sage: (ex.subs(a==55/98) - gegenbauer(100, 55/98, x)).is_trivial_zero()
|
|
2325
|
+
True
|
|
2326
|
+
|
|
2327
|
+
sage: # needs sage.symbolic
|
|
2328
|
+
sage: gegenbauer(2, -3, x)
|
|
2329
|
+
12*x^2 + 3
|
|
2330
|
+
sage: gegenbauer(120, -99/2, 3)
|
|
2331
|
+
1654502372608570682112687530178328494861923493372493824
|
|
2332
|
+
sage: gegenbauer(5, 9/2, x)
|
|
2333
|
+
21879/8*x^5 - 6435/4*x^3 + 1287/8*x
|
|
2334
|
+
sage: gegenbauer(15, 3/2, 5)
|
|
2335
|
+
3903412392243800
|
|
2336
|
+
|
|
2337
|
+
sage: derivative(gegenbauer(n, a, x), x) # needs sage.symbolic
|
|
2338
|
+
2*a*gegenbauer(n - 1, a + 1, x)
|
|
2339
|
+
sage: derivative(gegenbauer(3, a, x), x) # needs sage.symbolic
|
|
2340
|
+
4*(a + 2)*(a + 1)*a*x^2 - 2*(a + 1)*a
|
|
2341
|
+
sage: derivative(gegenbauer(n, a, x), a) # needs sage.symbolic
|
|
2342
|
+
Traceback (most recent call last):
|
|
2343
|
+
...
|
|
2344
|
+
RuntimeError: derivative w.r.t. to the second index is not supported yet
|
|
2345
|
+
|
|
2346
|
+
Numerical evaluation with the mpmath library::
|
|
2347
|
+
|
|
2348
|
+
sage: # needs mpmath
|
|
2349
|
+
sage: from mpmath import gegenbauer as gegenbauer_mp
|
|
2350
|
+
sage: from mpmath import mp
|
|
2351
|
+
sage: print(gegenbauer_mp(-7,0.5,0.3))
|
|
2352
|
+
0.1291811875
|
|
2353
|
+
sage: with mp.workdps(25):
|
|
2354
|
+
....: print(gegenbauer_mp(2+3j, -0.75, -1000j))
|
|
2355
|
+
(-5038991.358609026523401901 + 9414549.285447104177860806j)
|
|
2356
|
+
|
|
2357
|
+
TESTS:
|
|
2358
|
+
|
|
2359
|
+
Check that :issue:`17192` is fixed::
|
|
2360
|
+
|
|
2361
|
+
sage: x = PolynomialRing(QQ, 'x').gen()
|
|
2362
|
+
sage: ultraspherical(0, 1, x) # needs sage.symbolic
|
|
2363
|
+
1
|
|
2364
|
+
|
|
2365
|
+
sage: ultraspherical(-1, 1, x) # needs sage.symbolic
|
|
2366
|
+
Traceback (most recent call last):
|
|
2367
|
+
...
|
|
2368
|
+
RuntimeError: gegenb_eval: The index n must be a nonnegative integer
|
|
2369
|
+
|
|
2370
|
+
sage: ultraspherical(-7, 1, x) # needs sage.symbolic
|
|
2371
|
+
Traceback (most recent call last):
|
|
2372
|
+
...
|
|
2373
|
+
RuntimeError: gegenb_eval: The index n must be a nonnegative integer
|
|
2374
|
+
"""
|
|
2375
|
+
def __init__(self):
|
|
2376
|
+
r"""
|
|
2377
|
+
Init method for the ultraspherical polynomials.
|
|
2378
|
+
|
|
2379
|
+
EXAMPLES::
|
|
2380
|
+
|
|
2381
|
+
sage: loads(dumps(ultraspherical))
|
|
2382
|
+
gegenbauer
|
|
2383
|
+
sage: ultraspherical(x, x, x)._sympy_() # needs sympy sage.symbolic
|
|
2384
|
+
gegenbauer(x, x, x)
|
|
2385
|
+
"""
|
|
2386
|
+
GinacFunction.__init__(self, "gegenbauer", nargs=3, latex_name=r"C",
|
|
2387
|
+
conversions={'maxima': 'ultraspherical',
|
|
2388
|
+
'mathematica': 'GegenbauerC',
|
|
2389
|
+
'maple': 'GegenbauerC',
|
|
2390
|
+
'sympy': 'gegenbauer'})
|
|
2391
|
+
|
|
2392
|
+
|
|
2393
|
+
ultraspherical = Func_ultraspherical()
|
|
2394
|
+
gegenbauer = Func_ultraspherical()
|
|
2395
|
+
|
|
2396
|
+
|
|
2397
|
+
class Func_laguerre(OrthogonalFunction):
|
|
2398
|
+
"""
|
|
2399
|
+
REFERENCE:
|
|
2400
|
+
|
|
2401
|
+
- [AS1964]_ 22.5.16, page 778 and page 789.
|
|
2402
|
+
"""
|
|
2403
|
+
def __init__(self):
|
|
2404
|
+
r"""
|
|
2405
|
+
Init method for the Laguerre polynomials.
|
|
2406
|
+
|
|
2407
|
+
EXAMPLES::
|
|
2408
|
+
|
|
2409
|
+
sage: # needs sage.symbolic
|
|
2410
|
+
sage: n, x = var('n,x')
|
|
2411
|
+
sage: laguerre(x, x)._sympy_() # needs sympy
|
|
2412
|
+
laguerre(x, x)
|
|
2413
|
+
sage: maxima(laguerre(1, x, hold=True))
|
|
2414
|
+
1-_SAGE_VAR_x
|
|
2415
|
+
sage: maxima(laguerre(n, laguerre(n, x)))
|
|
2416
|
+
laguerre(_SAGE_VAR_n,laguerre(_SAGE_VAR_n,_SAGE_VAR_x))
|
|
2417
|
+
|
|
2418
|
+
TESTS::
|
|
2419
|
+
|
|
2420
|
+
sage: loads(dumps(laguerre))
|
|
2421
|
+
laguerre
|
|
2422
|
+
"""
|
|
2423
|
+
OrthogonalFunction.__init__(self, "laguerre", nargs=2, latex_name=r"L",
|
|
2424
|
+
conversions={'maxima': 'laguerre',
|
|
2425
|
+
'mathematica': 'LaguerreL',
|
|
2426
|
+
# 'fricas': 'laguerreL', 3 arguments ?
|
|
2427
|
+
'maple': 'LaguerreL',
|
|
2428
|
+
'sympy': 'laguerre'})
|
|
2429
|
+
|
|
2430
|
+
def _eval_(self, n, x, *args, **kwds):
|
|
2431
|
+
r"""
|
|
2432
|
+
Return an evaluation of this Laguerre polynomial expression.
|
|
2433
|
+
|
|
2434
|
+
EXAMPLES::
|
|
2435
|
+
|
|
2436
|
+
sage: x = PolynomialRing(QQ, 'x').gen()
|
|
2437
|
+
sage: laguerre(2, x) # needs mpmath
|
|
2438
|
+
1/2*x^2 - 2*x + 1
|
|
2439
|
+
sage: laguerre(3, x) # needs mpmath
|
|
2440
|
+
-1/6*x^3 + 3/2*x^2 - 3*x + 1
|
|
2441
|
+
sage: laguerre(2, 2) # needs mpmath
|
|
2442
|
+
-1
|
|
2443
|
+
sage: laguerre(-1, x) # needs sage.symbolic
|
|
2444
|
+
e^x
|
|
2445
|
+
sage: laguerre(-6, x) # needs sage.symbolic
|
|
2446
|
+
1/120*(x^5 + 25*x^4 + 200*x^3 + 600*x^2 + 600*x + 120)*e^x
|
|
2447
|
+
sage: laguerre(-9,2) # needs sage.symbolic
|
|
2448
|
+
66769/315*e^2
|
|
2449
|
+
"""
|
|
2450
|
+
from sage.rings.integer import Integer
|
|
2451
|
+
from sage.functions.log import exp
|
|
2452
|
+
ret = self._eval_special_values_(n, x)
|
|
2453
|
+
if ret is not None:
|
|
2454
|
+
return ret
|
|
2455
|
+
if isinstance(n, (Integer, int)):
|
|
2456
|
+
if n >= 0 and not hasattr(x, 'prec'):
|
|
2457
|
+
return self._pol_laguerre(n, x)
|
|
2458
|
+
elif n < 0:
|
|
2459
|
+
return exp(x)*laguerre(-n-1, -x)
|
|
2460
|
+
|
|
2461
|
+
def _eval_special_values_(self, n, x):
|
|
2462
|
+
"""
|
|
2463
|
+
Special values known.
|
|
2464
|
+
|
|
2465
|
+
EXAMPLES::
|
|
2466
|
+
|
|
2467
|
+
sage: laguerre(0, 0) # needs mpmath
|
|
2468
|
+
1
|
|
2469
|
+
sage: laguerre(1, x) # needs sage.symbolic
|
|
2470
|
+
-x + 1
|
|
2471
|
+
"""
|
|
2472
|
+
if n == 0 or x == 0:
|
|
2473
|
+
return ZZ(1)
|
|
2474
|
+
if n == 1:
|
|
2475
|
+
return ZZ(1) - x
|
|
2476
|
+
|
|
2477
|
+
def _pol_laguerre(self, n, x):
|
|
2478
|
+
"""
|
|
2479
|
+
Fast creation of Laguerre polynomial.
|
|
2480
|
+
|
|
2481
|
+
EXAMPLES::
|
|
2482
|
+
|
|
2483
|
+
sage: laguerre(3, sin(x)) # needs sage.symbolic
|
|
2484
|
+
-1/6*sin(x)^3 + 3/2*sin(x)^2 - 3*sin(x) + 1
|
|
2485
|
+
sage: R.<x> = PolynomialRing(QQ, 'x')
|
|
2486
|
+
sage: laguerre(4, x) # needs mpmath
|
|
2487
|
+
1/24*x^4 - 2/3*x^3 + 3*x^2 - 4*x + 1
|
|
2488
|
+
sage: laguerre(4, x + 1) # needs mpmath
|
|
2489
|
+
1/24*(x + 1)^4 - 2/3*(x + 1)^3 + 3*(x + 1)^2 - 4*x - 3
|
|
2490
|
+
sage: laguerre(10, 1 + I) # needs sage.symbolic
|
|
2491
|
+
142511/113400*I + 95867/22680
|
|
2492
|
+
"""
|
|
2493
|
+
if hasattr(x, 'pyobject'):
|
|
2494
|
+
try:
|
|
2495
|
+
x = x.pyobject()
|
|
2496
|
+
except TypeError:
|
|
2497
|
+
pass
|
|
2498
|
+
return SR(sum(binomial(n, k) * (-1)**k / factorial(k) * x**k
|
|
2499
|
+
for k in range(n + 1)))
|
|
2500
|
+
|
|
2501
|
+
def _evalf_(self, n, x, **kwds):
|
|
2502
|
+
"""
|
|
2503
|
+
Return the evaluation of `laguerre(n,x)` with floating point `x`.
|
|
2504
|
+
|
|
2505
|
+
EXAMPLES::
|
|
2506
|
+
|
|
2507
|
+
sage: laguerre(100, RealField(300)(pi)) # needs sage.symbolic
|
|
2508
|
+
-0.638322077840648311606324...
|
|
2509
|
+
sage: laguerre(10, 1. + I) # needs sage.symbolic
|
|
2510
|
+
4.22694003527337 + 1.25671075837743*I
|
|
2511
|
+
sage: laguerre(-9, 2.) # needs sage.symbolic
|
|
2512
|
+
1566.22186244286
|
|
2513
|
+
"""
|
|
2514
|
+
the_parent = kwds.get('parent', None)
|
|
2515
|
+
if the_parent is None:
|
|
2516
|
+
the_parent = parent(x)
|
|
2517
|
+
if n < 0:
|
|
2518
|
+
# work around mpmath issue 307
|
|
2519
|
+
from sage.functions.log import exp
|
|
2520
|
+
return exp(x) * _mpmath_utils_call(_mpmath_laguerre, -n-1, 0, -x, parent=the_parent)
|
|
2521
|
+
else:
|
|
2522
|
+
return _mpmath_utils_call(_mpmath_laguerre, n, 0, x, parent=the_parent)
|
|
2523
|
+
|
|
2524
|
+
def _derivative_(self, n, x, *args, **kwds):
|
|
2525
|
+
"""
|
|
2526
|
+
Return the derivative of `laguerre(n,x)`.
|
|
2527
|
+
|
|
2528
|
+
EXAMPLES::
|
|
2529
|
+
|
|
2530
|
+
sage: n = var('n') # needs sage.symbolic
|
|
2531
|
+
sage: diff(laguerre(n, x), x) # needs sage.symbolic
|
|
2532
|
+
-gen_laguerre(n - 1, 1, x)
|
|
2533
|
+
|
|
2534
|
+
TESTS::
|
|
2535
|
+
|
|
2536
|
+
sage: diff(laguerre(x, x)) # needs sage.symbolic
|
|
2537
|
+
Traceback (most recent call last):
|
|
2538
|
+
...
|
|
2539
|
+
NotImplementedError: Derivative w.r.t. to the index is not supported.
|
|
2540
|
+
"""
|
|
2541
|
+
diff_param = kwds['diff_param']
|
|
2542
|
+
if diff_param == 0:
|
|
2543
|
+
raise NotImplementedError("Derivative w.r.t. to the index is not supported.")
|
|
2544
|
+
if diff_param == 1:
|
|
2545
|
+
return -gen_laguerre(n-1, 1, x)
|
|
2546
|
+
raise ValueError(f"illegal differentiation parameter {diff_param}")
|
|
2547
|
+
|
|
2548
|
+
|
|
2549
|
+
laguerre = Func_laguerre()
|
|
2550
|
+
|
|
2551
|
+
|
|
2552
|
+
class Func_gen_laguerre(OrthogonalFunction):
|
|
2553
|
+
"""
|
|
2554
|
+
REFERENCE:
|
|
2555
|
+
|
|
2556
|
+
- [AS1964]_ 22.5.16, page 778 and page 789.
|
|
2557
|
+
"""
|
|
2558
|
+
def __init__(self):
|
|
2559
|
+
r"""
|
|
2560
|
+
Init method for the Laguerre polynomials.
|
|
2561
|
+
|
|
2562
|
+
EXAMPLES::
|
|
2563
|
+
|
|
2564
|
+
sage: # needs sage.symbolic
|
|
2565
|
+
sage: a, n, x = var('a, n, x')
|
|
2566
|
+
sage: gen_laguerre(x, x, x)._sympy_() # needs sympy
|
|
2567
|
+
assoc_laguerre(x, x, x)
|
|
2568
|
+
sage: maxima(gen_laguerre(1, 2, x, hold=True))
|
|
2569
|
+
3*(1-_SAGE_VAR_x/3)
|
|
2570
|
+
sage: maxima(gen_laguerre(n, a, gen_laguerre(n, a, x)))
|
|
2571
|
+
gen_laguerre(_SAGE_VAR_n,_SAGE_VAR_a, gen_laguerre(_SAGE_VAR_n,_SAGE_VAR_a,_SAGE_VAR_x))
|
|
2572
|
+
|
|
2573
|
+
TESTS::
|
|
2574
|
+
|
|
2575
|
+
sage: loads(dumps(gen_laguerre))
|
|
2576
|
+
gen_laguerre
|
|
2577
|
+
"""
|
|
2578
|
+
OrthogonalFunction.__init__(self, "gen_laguerre", nargs=3, latex_name=r"L",
|
|
2579
|
+
conversions={'maxima': 'gen_laguerre',
|
|
2580
|
+
'mathematica': 'LaguerreL',
|
|
2581
|
+
'maple': 'LaguerreL',
|
|
2582
|
+
'sympy': 'assoc_laguerre'})
|
|
2583
|
+
|
|
2584
|
+
def _eval_(self, n, a, x, *args, **kwds):
|
|
2585
|
+
r"""
|
|
2586
|
+
Return an evaluation of this Laguerre polynomial expression.
|
|
2587
|
+
|
|
2588
|
+
EXAMPLES::
|
|
2589
|
+
|
|
2590
|
+
sage: # needs sage.symbolic
|
|
2591
|
+
sage: gen_laguerre(2, 1, x)
|
|
2592
|
+
1/2*x^2 - 3*x + 3
|
|
2593
|
+
sage: gen_laguerre(2, 1/2, x)
|
|
2594
|
+
1/2*x^2 - 5/2*x + 15/8
|
|
2595
|
+
sage: gen_laguerre(2, -1/2, x)
|
|
2596
|
+
1/2*x^2 - 3/2*x + 3/8
|
|
2597
|
+
sage: gen_laguerre(2, 0, x)
|
|
2598
|
+
1/2*x^2 - 2*x + 1
|
|
2599
|
+
sage: gen_laguerre(3, 0, x)
|
|
2600
|
+
-1/6*x^3 + 3/2*x^2 - 3*x + 1
|
|
2601
|
+
"""
|
|
2602
|
+
from sage.rings.integer import Integer
|
|
2603
|
+
ret = self._eval_special_values_(n, a, x)
|
|
2604
|
+
if ret is not None:
|
|
2605
|
+
return ret
|
|
2606
|
+
if isinstance(n, Integer):
|
|
2607
|
+
if n >= 0 and not hasattr(x, 'prec'):
|
|
2608
|
+
return self._pol_gen_laguerre(n, a, x)
|
|
2609
|
+
|
|
2610
|
+
def _eval_special_values_(self, n, a, x):
|
|
2611
|
+
"""
|
|
2612
|
+
Special values known.
|
|
2613
|
+
|
|
2614
|
+
EXAMPLES::
|
|
2615
|
+
|
|
2616
|
+
sage: gen_laguerre(0, 1, pi) # needs sage.symbolic
|
|
2617
|
+
1
|
|
2618
|
+
sage: gen_laguerre(1, 2, x) # needs sage.symbolic
|
|
2619
|
+
-x + 3
|
|
2620
|
+
sage: gen_laguerre(3, 4, 0) # needs mpmath
|
|
2621
|
+
35
|
|
2622
|
+
"""
|
|
2623
|
+
if n == 0:
|
|
2624
|
+
return ZZ(1)
|
|
2625
|
+
if n == 1:
|
|
2626
|
+
return ZZ(1) + a - x
|
|
2627
|
+
if a == 0:
|
|
2628
|
+
return laguerre(n, x)
|
|
2629
|
+
if x == 0:
|
|
2630
|
+
from sage.arith.misc import binomial
|
|
2631
|
+
return binomial(n+a, n)
|
|
2632
|
+
|
|
2633
|
+
def _pol_gen_laguerre(self, n, a, x):
|
|
2634
|
+
"""
|
|
2635
|
+
EXAMPLES::
|
|
2636
|
+
|
|
2637
|
+
sage: gen_laguerre(3, 1/2, sin(x)) # needs sage.symbolic
|
|
2638
|
+
-1/6*sin(x)^3 + 7/4*sin(x)^2 - 35/8*sin(x) + 35/16
|
|
2639
|
+
sage: R.<x> = PolynomialRing(QQ, 'x')
|
|
2640
|
+
sage: gen_laguerre(4, -1/2, x) # needs mpmath sage.libs.pari
|
|
2641
|
+
1/24*x^4 - 7/12*x^3 + 35/16*x^2 - 35/16*x + 35/128
|
|
2642
|
+
sage: gen_laguerre(4, -1/2, x + 1) # needs mpmath sage.libs.pari
|
|
2643
|
+
1/24*(x + 1)^4 - 7/12*(x + 1)^3 + 35/16*(x + 1)^2 - 35/16*x - 245/128
|
|
2644
|
+
sage: gen_laguerre(10, 1, 1 + I) # needs sage.symbolic
|
|
2645
|
+
25189/2100*I + 11792/2835
|
|
2646
|
+
"""
|
|
2647
|
+
return sum(binomial(n + a, n - k) * (-1)**k / factorial(k) * x**k
|
|
2648
|
+
for k in range(n + 1))
|
|
2649
|
+
|
|
2650
|
+
def _evalf_(self, n, a, x, **kwds):
|
|
2651
|
+
"""
|
|
2652
|
+
EXAMPLES::
|
|
2653
|
+
|
|
2654
|
+
sage: gen_laguerre(100, 1, RealField(300)(pi)) # needs sage.symbolic
|
|
2655
|
+
-0.89430788373354541911...
|
|
2656
|
+
sage: gen_laguerre(10,1/2,1.+I) # needs sage.symbolic
|
|
2657
|
+
5.34469635574906 + 5.23754057922902*I
|
|
2658
|
+
"""
|
|
2659
|
+
the_parent = kwds.get('parent', None)
|
|
2660
|
+
if the_parent is None:
|
|
2661
|
+
the_parent = parent(x)
|
|
2662
|
+
return _mpmath_utils_call(_mpmath_laguerre, n, a, x, parent=the_parent)
|
|
2663
|
+
|
|
2664
|
+
def _derivative_(self, n, a, x, diff_param):
|
|
2665
|
+
"""
|
|
2666
|
+
Return the derivative of `gen_laguerre(n,a,x)`.
|
|
2667
|
+
|
|
2668
|
+
EXAMPLES::
|
|
2669
|
+
|
|
2670
|
+
sage: a, n = var('a,n') # needs sage.symbolic
|
|
2671
|
+
sage: diff(gen_laguerre(n,a,x), x) # needs sage.symbolic
|
|
2672
|
+
-gen_laguerre(n - 1, a + 1, x)
|
|
2673
|
+
sage: gen_laguerre(n,a,x).diff(a) # needs sage.symbolic
|
|
2674
|
+
Traceback (most recent call last):
|
|
2675
|
+
...
|
|
2676
|
+
NotImplementedError: Derivative w.r.t. to the second index is not supported.
|
|
2677
|
+
|
|
2678
|
+
TESTS::
|
|
2679
|
+
|
|
2680
|
+
sage: diff(gen_laguerre(n,a,x), n) # needs sage.symbolic
|
|
2681
|
+
Traceback (most recent call last):
|
|
2682
|
+
...
|
|
2683
|
+
NotImplementedError: Derivative w.r.t. to the index is not supported.
|
|
2684
|
+
"""
|
|
2685
|
+
if diff_param == 0:
|
|
2686
|
+
raise NotImplementedError("Derivative w.r.t. to the index is not supported.")
|
|
2687
|
+
elif diff_param == 1:
|
|
2688
|
+
raise NotImplementedError("Derivative w.r.t. to the second index is not supported.")
|
|
2689
|
+
elif diff_param == 2:
|
|
2690
|
+
return -gen_laguerre(n - 1, a + 1, x)
|
|
2691
|
+
else:
|
|
2692
|
+
raise ValueError("illegal differentiation parameter {}".format(diff_param))
|
|
2693
|
+
|
|
2694
|
+
|
|
2695
|
+
gen_laguerre = Func_gen_laguerre()
|
|
2696
|
+
|
|
2697
|
+
|
|
2698
|
+
class Func_krawtchouk(OrthogonalFunction):
|
|
2699
|
+
r"""
|
|
2700
|
+
Krawtchouk polynomials `K_j(x; n, p)`.
|
|
2701
|
+
|
|
2702
|
+
INPUT:
|
|
2703
|
+
|
|
2704
|
+
- ``j`` -- the degree
|
|
2705
|
+
- ``x`` -- the independent variable `x`
|
|
2706
|
+
- ``n`` -- the number of discrete points
|
|
2707
|
+
- ``p`` -- the parameter `p`
|
|
2708
|
+
|
|
2709
|
+
.. SEEALSO::
|
|
2710
|
+
|
|
2711
|
+
:func:`sage.coding.delsarte_bounds.krawtchouk`
|
|
2712
|
+
`\bar{K}^{n,q}_l(x)`, which are related by
|
|
2713
|
+
|
|
2714
|
+
.. MATH::
|
|
2715
|
+
|
|
2716
|
+
(-q)^j \bar{K}^{n,q^{-1}}_j(x) = K_j(x; n, 1-q).
|
|
2717
|
+
|
|
2718
|
+
EXAMPLES:
|
|
2719
|
+
|
|
2720
|
+
We verify the orthogonality for `n = 4`::
|
|
2721
|
+
|
|
2722
|
+
sage: n = 4
|
|
2723
|
+
sage: p = SR.var('p') # needs sage.symbolic
|
|
2724
|
+
sage: matrix([[sum(binomial(n,m) * p**m * (1-p)**(n-m) # needs sage.symbolic
|
|
2725
|
+
....: * krawtchouk(i,m,n,p) * krawtchouk(j,m,n,p)
|
|
2726
|
+
....: for m in range(n+1)).expand().factor()
|
|
2727
|
+
....: for i in range(n+1)] for j in range(n+1)])
|
|
2728
|
+
[ 1 0 0 0 0]
|
|
2729
|
+
[ 0 -4*(p - 1)*p 0 0 0]
|
|
2730
|
+
[ 0 0 6*(p - 1)^2*p^2 0 0]
|
|
2731
|
+
[ 0 0 0 -4*(p - 1)^3*p^3 0]
|
|
2732
|
+
[ 0 0 0 0 (p - 1)^4*p^4]
|
|
2733
|
+
|
|
2734
|
+
We verify the relationship between the Krawtchouk implementations::
|
|
2735
|
+
|
|
2736
|
+
sage: q = SR.var('q') # needs sage.symbolic
|
|
2737
|
+
sage: all(codes.bounds.krawtchouk(n, 1/q, j, x)*(-q)^j # needs sage.symbolic
|
|
2738
|
+
....: == krawtchouk(j, x, n, 1-q) for j in range(n+1))
|
|
2739
|
+
True
|
|
2740
|
+
"""
|
|
2741
|
+
def __init__(self):
|
|
2742
|
+
"""
|
|
2743
|
+
Initialize ``self``.
|
|
2744
|
+
|
|
2745
|
+
EXAMPLES::
|
|
2746
|
+
|
|
2747
|
+
sage: k, x, n, p = var('k,x,n,p') # needs sage.symbolic
|
|
2748
|
+
sage: TestSuite(krawtchouk).run()
|
|
2749
|
+
sage: TestSuite(krawtchouk(k, x, n, p)).run() # needs sage.symbolic
|
|
2750
|
+
sage: TestSuite(krawtchouk(3, x, n, p)).run() # needs sage.symbolic
|
|
2751
|
+
"""
|
|
2752
|
+
super().__init__(name='krawtchouk', nargs=4, latex_name='K')
|
|
2753
|
+
|
|
2754
|
+
def eval_formula(self, k, x, n, p):
|
|
2755
|
+
r"""
|
|
2756
|
+
Evaluate ``self`` using an explicit formula.
|
|
2757
|
+
|
|
2758
|
+
EXAMPLES::
|
|
2759
|
+
|
|
2760
|
+
sage: x, n, p = var('x,n,p') # needs sage.symbolic
|
|
2761
|
+
sage: krawtchouk.eval_formula(3, x, n, p).expand().collect(x) # needs sage.symbolic
|
|
2762
|
+
-1/6*n^3*p^3 + 1/2*n^2*p^3 - 1/3*n*p^3 - 1/2*(n*p - 2*p + 1)*x^2
|
|
2763
|
+
+ 1/6*x^3 + 1/6*(3*n^2*p^2 - 9*n*p^2 + 3*n*p + 6*p^2 - 6*p + 2)*x
|
|
2764
|
+
"""
|
|
2765
|
+
q = 1 - p
|
|
2766
|
+
return sum((-1)**(k-i) * binomial(n-x, k-i) * binomial(x, i) * p**(k-i) * q**i
|
|
2767
|
+
for i in range(k+1))
|
|
2768
|
+
|
|
2769
|
+
def _eval_(self, j, x, n, p, *args, **kwds):
|
|
2770
|
+
r"""
|
|
2771
|
+
Return an evaluation of the Krawtchouk polynomial `K_j(x; n, p)`.
|
|
2772
|
+
|
|
2773
|
+
EXAMPLES::
|
|
2774
|
+
|
|
2775
|
+
sage: # needs sage.symbolic
|
|
2776
|
+
sage: k, x, n, p = var('k,x,n,p')
|
|
2777
|
+
sage: krawtchouk(3, x, 5, p).expand()
|
|
2778
|
+
-10*p^3 + 6*p^2*x - 3/2*p*x^2 + 1/6*x^3 + 3/2*p*x - 1/2*x^2 + 1/3*x
|
|
2779
|
+
sage: krawtchouk(k, x, 5, p)
|
|
2780
|
+
(-1)^k*p^k*binomial(5, k)*hypergeometric((-k, -x), (-5,), 1/p)
|
|
2781
|
+
sage: krawtchouk(2, x, n, p).collect(x)
|
|
2782
|
+
1/2*n^2*p^2 - 1/2*n*p^2 - 1/2*(2*n*p - 2*p + 1)*x + 1/2*x^2
|
|
2783
|
+
sage: krawtchouk(k, x, n, p)
|
|
2784
|
+
(-1)^k*p^k*binomial(n, k)*hypergeometric((-k, -x), (-n,), 1/p)
|
|
2785
|
+
|
|
2786
|
+
sage: k3_hypergeo = krawtchouk(k,x,n,p)(k=3).simplify_hypergeometric() # needs sage.symbolic
|
|
2787
|
+
sage: bool(k3_hypergeo == krawtchouk(3,x,n,p)) # needs sage.symbolic
|
|
2788
|
+
True
|
|
2789
|
+
|
|
2790
|
+
sage: krawtchouk(2, x, n, p, hold=True) # needs sage.symbolic
|
|
2791
|
+
krawtchouk(2, x, n, p)
|
|
2792
|
+
"""
|
|
2793
|
+
if kwds.get('hold', False):
|
|
2794
|
+
return None
|
|
2795
|
+
if j not in ZZ or j < 0:
|
|
2796
|
+
from sage.functions.hypergeometric import hypergeometric
|
|
2797
|
+
return (-1)**j * binomial(n, j) * p**j * hypergeometric([-j, -x], [-n], 1/p)
|
|
2798
|
+
try:
|
|
2799
|
+
return self.eval_formula(j, x, n, p)
|
|
2800
|
+
except (TypeError, ValueError):
|
|
2801
|
+
return self.eval_recursive(j, x, n, p)
|
|
2802
|
+
|
|
2803
|
+
def eval_recursive(self, j, x, n, p, *args, **kwds):
|
|
2804
|
+
r"""
|
|
2805
|
+
Return the Krawtchouk polynomial `K_j(x; n, p)` using the
|
|
2806
|
+
recursive formula.
|
|
2807
|
+
|
|
2808
|
+
EXAMPLES::
|
|
2809
|
+
|
|
2810
|
+
sage: # needs sage.symbolic
|
|
2811
|
+
sage: x, n, p = var('x,n,p')
|
|
2812
|
+
sage: krawtchouk.eval_recursive(0, x, n, p)
|
|
2813
|
+
1
|
|
2814
|
+
sage: krawtchouk.eval_recursive(1, x, n, p)
|
|
2815
|
+
-n*p + x
|
|
2816
|
+
sage: krawtchouk.eval_recursive(2, x, n, p).collect(x)
|
|
2817
|
+
1/2*n^2*p^2 + 1/2*n*(p - 1)*p - n*p^2 + 1/2*n*p
|
|
2818
|
+
- 1/2*(2*n*p - 2*p + 1)*x + 1/2*x^2
|
|
2819
|
+
sage: bool(krawtchouk.eval_recursive(2, x, n, p) == krawtchouk(2, x, n, p))
|
|
2820
|
+
True
|
|
2821
|
+
sage: bool(krawtchouk.eval_recursive(3, x, n, p) == krawtchouk(3, x, n, p))
|
|
2822
|
+
True
|
|
2823
|
+
sage: bool(krawtchouk.eval_recursive(4, x, n, p) == krawtchouk(4, x, n, p))
|
|
2824
|
+
True
|
|
2825
|
+
|
|
2826
|
+
sage: M = matrix([[-1/2, -1], [1, 0]]) # needs sage.modules
|
|
2827
|
+
sage: krawtchouk.eval_recursive(2, M, 3, 1/2) # needs sage.modules
|
|
2828
|
+
[ 9/8 7/4]
|
|
2829
|
+
[-7/4 1/4]
|
|
2830
|
+
"""
|
|
2831
|
+
if j == 0:
|
|
2832
|
+
return parent(x).one()
|
|
2833
|
+
elif j == 1:
|
|
2834
|
+
return x - n * p
|
|
2835
|
+
q = 1 - p
|
|
2836
|
+
tm2 = p * q * (n - (j-1) + 1) * krawtchouk.eval_recursive(j-2, x, n, p)
|
|
2837
|
+
tm1 = (x - p*(n-(j-1)) - (j-1)*q) * krawtchouk.eval_recursive(j-1, x, n, p)
|
|
2838
|
+
return (tm1 - tm2) / j
|
|
2839
|
+
|
|
2840
|
+
|
|
2841
|
+
krawtchouk = Func_krawtchouk()
|
|
2842
|
+
|
|
2843
|
+
|
|
2844
|
+
class Func_meixner(OrthogonalFunction):
|
|
2845
|
+
r"""
|
|
2846
|
+
Meixner polynomials `M_n(x; b, c)`.
|
|
2847
|
+
|
|
2848
|
+
INPUT:
|
|
2849
|
+
|
|
2850
|
+
- ``n`` -- the degree
|
|
2851
|
+
- ``x`` -- the independent variable `x`
|
|
2852
|
+
- ``b``, ``c`` -- the parameters `b`, `c`
|
|
2853
|
+
"""
|
|
2854
|
+
def __init__(self):
|
|
2855
|
+
"""
|
|
2856
|
+
Initialize ``self``.
|
|
2857
|
+
|
|
2858
|
+
EXAMPLES::
|
|
2859
|
+
|
|
2860
|
+
sage: n, x, b, c = var('n,x,b,c') # needs sage.symbolic
|
|
2861
|
+
sage: TestSuite(meixner).run()
|
|
2862
|
+
sage: TestSuite(meixner(3, x, b, c)).run() # needs sage.symbolic
|
|
2863
|
+
sage: TestSuite(meixner(n, x, b, c)).run() # needs sage.symbolic
|
|
2864
|
+
"""
|
|
2865
|
+
super().__init__(name='meixner', nargs=4, latex_name='M')
|
|
2866
|
+
|
|
2867
|
+
def eval_formula(self, n, x, b, c):
|
|
2868
|
+
r"""
|
|
2869
|
+
Evaluate ``self`` using an explicit formula.
|
|
2870
|
+
|
|
2871
|
+
EXAMPLES::
|
|
2872
|
+
|
|
2873
|
+
sage: x, b, c = var('x,b,c') # needs sage.symbolic
|
|
2874
|
+
sage: meixner.eval_formula(3, x, b, c).expand().collect(x) # needs sage.symbolic
|
|
2875
|
+
-x^3*(3/c - 3/c^2 + 1/c^3 - 1) + b^3
|
|
2876
|
+
+ 3*(b - 2*b/c + b/c^2 - 1/c - 1/c^2 + 1/c^3 + 1)*x^2 + 3*b^2
|
|
2877
|
+
+ (3*b^2 + 6*b - 3*b^2/c - 3*b/c - 3*b/c^2 - 2/c^3 + 2)*x + 2*b
|
|
2878
|
+
"""
|
|
2879
|
+
from sage.misc.misc_c import prod
|
|
2880
|
+
|
|
2881
|
+
def P(val, k):
|
|
2882
|
+
return prod(val + j for j in range(k))
|
|
2883
|
+
return sum((-1)**k * binomial(n, k) * binomial(x, k) * factorial(k)
|
|
2884
|
+
* P(x + b, n - k) * c**-k
|
|
2885
|
+
for k in range(n+1))
|
|
2886
|
+
|
|
2887
|
+
def _eval_(self, n, x, b, c, *args, **kwds):
|
|
2888
|
+
r"""
|
|
2889
|
+
Return an evaluation of the Meixner polynomial `M_n(x; b, c)`.
|
|
2890
|
+
|
|
2891
|
+
EXAMPLES::
|
|
2892
|
+
|
|
2893
|
+
sage: # needs sage.symbolic
|
|
2894
|
+
sage: n, x, b, c = var('n,x,b,c')
|
|
2895
|
+
sage: meixner(2, x, b, c).collect(x)
|
|
2896
|
+
-x^2*(2/c - 1/c^2 - 1) + b^2 + (2*b - 2*b/c - 1/c^2 + 1)*x + b
|
|
2897
|
+
sage: meixner(3, x, b, c).factor().collect(x)
|
|
2898
|
+
-x^3*(3/c - 3/c^2 + 1/c^3 - 1) + b^3
|
|
2899
|
+
+ 3*(b - 2*b/c + b/c^2 - 1/c - 1/c^2 + 1/c^3 + 1)*x^2 + 3*b^2
|
|
2900
|
+
+ (3*b^2 + 6*b - 3*b^2/c - 3*b/c - 3*b/c^2 - 2/c^3 + 2)*x + 2*b
|
|
2901
|
+
sage: meixner(n, x, b, c)
|
|
2902
|
+
gamma(b + n)*hypergeometric((-n, -x), (b,), -1/c + 1)/gamma(b)
|
|
2903
|
+
|
|
2904
|
+
sage: # needs sage.symbolic
|
|
2905
|
+
sage: n3_hypergeo = meixner(n, x, b, c)(n=3).simplify_hypergeometric()
|
|
2906
|
+
sage: n3_hypergeo = n3_hypergeo.simplify_full()
|
|
2907
|
+
sage: bool(n3_hypergeo == meixner(3, x, b, c))
|
|
2908
|
+
True
|
|
2909
|
+
sage: n4_hypergeo = meixner(n, x, b, c)(n=4).simplify_hypergeometric()
|
|
2910
|
+
sage: n4_hypergeo = n4_hypergeo.simplify_full()
|
|
2911
|
+
sage: bool(n4_hypergeo == meixner(4, x, b, c))
|
|
2912
|
+
True
|
|
2913
|
+
|
|
2914
|
+
sage: meixner(2, x, b, c, hold=True) # needs sage.symbolic
|
|
2915
|
+
meixner(2, x, b, c)
|
|
2916
|
+
"""
|
|
2917
|
+
if kwds.get('hold', False):
|
|
2918
|
+
return None
|
|
2919
|
+
if n not in ZZ or n < 0:
|
|
2920
|
+
from sage.functions.hypergeometric import hypergeometric
|
|
2921
|
+
from sage.functions.gamma import gamma
|
|
2922
|
+
return gamma(b + n) / gamma(b) * hypergeometric([-n, -x], [b], 1 - 1/c)
|
|
2923
|
+
try:
|
|
2924
|
+
return self.eval_formula(n, x, b, c)
|
|
2925
|
+
except (TypeError, ValueError):
|
|
2926
|
+
return self.eval_recursive(n, x, b, c)
|
|
2927
|
+
|
|
2928
|
+
def eval_recursive(self, n, x, b, c, *args, **kwds):
|
|
2929
|
+
r"""
|
|
2930
|
+
Return the Meixner polynomial `M_n(x; b, c)` using the
|
|
2931
|
+
recursive formula.
|
|
2932
|
+
|
|
2933
|
+
EXAMPLES::
|
|
2934
|
+
|
|
2935
|
+
sage: # needs sage.symbolic
|
|
2936
|
+
sage: x, b, c = var('x,b,c')
|
|
2937
|
+
sage: meixner.eval_recursive(0, x, b, c)
|
|
2938
|
+
1
|
|
2939
|
+
sage: meixner.eval_recursive(1, x, b, c)
|
|
2940
|
+
-x*(1/c - 1) + b
|
|
2941
|
+
sage: meixner.eval_recursive(2, x, b, c).simplify_full().collect(x)
|
|
2942
|
+
-x^2*(2/c - 1/c^2 - 1) + b^2 + (2*b - 2*b/c - 1/c^2 + 1)*x + b
|
|
2943
|
+
sage: bool(meixner(2, x, b, c) == meixner.eval_recursive(2, x, b, c))
|
|
2944
|
+
True
|
|
2945
|
+
sage: bool(meixner(3, x, b, c) == meixner.eval_recursive(3, x, b, c))
|
|
2946
|
+
True
|
|
2947
|
+
sage: bool(meixner(4, x, b, c) == meixner.eval_recursive(4, x, b, c))
|
|
2948
|
+
True
|
|
2949
|
+
sage: M = matrix([[-1/2, -1], [1, 0]])
|
|
2950
|
+
sage: ret = meixner.eval_recursive(2, M, b, c).simplify_full().factor()
|
|
2951
|
+
sage: for i in range(2): # make the output polynomials in 1/c
|
|
2952
|
+
....: for j in range(2):
|
|
2953
|
+
....: ret[i, j] = ret[i, j].collect(c)
|
|
2954
|
+
sage: ret
|
|
2955
|
+
[b^2 + 1/2*(2*b + 3)/c - 1/4/c^2 - 5/4 -2*b + (2*b - 1)/c + 3/2/c^2 - 1/2]
|
|
2956
|
+
[ 2*b - (2*b - 1)/c - 3/2/c^2 + 1/2 b^2 + b + 2/c - 1/c^2 - 1]
|
|
2957
|
+
"""
|
|
2958
|
+
if n == 0:
|
|
2959
|
+
return parent(x).one()
|
|
2960
|
+
elif n == 1:
|
|
2961
|
+
return (1 - 1/c) * x + b
|
|
2962
|
+
tm2 = (b+n-1) * (b+n-2) * (n - 1) * meixner.eval_recursive(n-2, x, b, c)
|
|
2963
|
+
tm1 = (b+n-1) * ((c-1) * x + n-1 + (n-1+b) * c) * meixner.eval_recursive(n-1, x, b, c)
|
|
2964
|
+
return (tm1 - tm2) / (c * (n - 1 + b))
|
|
2965
|
+
|
|
2966
|
+
|
|
2967
|
+
meixner = Func_meixner()
|
|
2968
|
+
|
|
2969
|
+
|
|
2970
|
+
class Func_hahn(OrthogonalFunction):
|
|
2971
|
+
r"""
|
|
2972
|
+
Hahn polynomials `Q_k(x; a, b, n)`.
|
|
2973
|
+
|
|
2974
|
+
INPUT:
|
|
2975
|
+
|
|
2976
|
+
- ``k`` -- the degree
|
|
2977
|
+
- ``x`` -- the independent variable `x`
|
|
2978
|
+
- ``a``, ``b`` -- the parameters `a`, `b`
|
|
2979
|
+
- ``n`` -- the number of discrete points
|
|
2980
|
+
|
|
2981
|
+
EXAMPLES:
|
|
2982
|
+
|
|
2983
|
+
We verify the orthogonality for `n = 3`::
|
|
2984
|
+
|
|
2985
|
+
sage: # needs sage.symbolic
|
|
2986
|
+
sage: n = 2
|
|
2987
|
+
sage: a, b = SR.var('a,b')
|
|
2988
|
+
sage: def rho(k, a, b, n):
|
|
2989
|
+
....: return binomial(a + k, k) * binomial(b + n - k, n - k)
|
|
2990
|
+
sage: M = matrix([[sum(rho(k, a, b, n)
|
|
2991
|
+
....: * hahn(i, k, a, b, n) * hahn(j, k, a, b, n)
|
|
2992
|
+
....: for k in range(n + 1)).expand().factor()
|
|
2993
|
+
....: for i in range(n+1)] for j in range(n+1)])
|
|
2994
|
+
sage: M = M.factor()
|
|
2995
|
+
sage: P = rising_factorial
|
|
2996
|
+
sage: def diag(i, a, b, n):
|
|
2997
|
+
....: return ((-1)^i * factorial(i) * P(b + 1, i) * P(i + a + b + 1, n + 1)
|
|
2998
|
+
....: / (factorial(n) * (2*i + a + b + 1) * P(-n, i) * P(a + 1, i)))
|
|
2999
|
+
sage: all(M[i,i] == diag(i, a, b, n) for i in range(3))
|
|
3000
|
+
True
|
|
3001
|
+
sage: all(M[i,j] == 0 for i in range(3) for j in range(3) if i != j)
|
|
3002
|
+
True
|
|
3003
|
+
"""
|
|
3004
|
+
def __init__(self):
|
|
3005
|
+
"""
|
|
3006
|
+
Initialize ``self``.
|
|
3007
|
+
|
|
3008
|
+
EXAMPLES::
|
|
3009
|
+
|
|
3010
|
+
sage: k, x, a, b, n = var('k,x,a,b,n') # needs sage.symbolic
|
|
3011
|
+
sage: TestSuite(hahn).run()
|
|
3012
|
+
sage: TestSuite(hahn(3, x, a, b, n)).run() # needs sage.symbolic
|
|
3013
|
+
sage: TestSuite(hahn(k, x, a, b, n)).run(skip='_test_category') # needs sage.symbolic
|
|
3014
|
+
"""
|
|
3015
|
+
super().__init__(name='hahn', nargs=5, latex_name='Q')
|
|
3016
|
+
|
|
3017
|
+
def eval_formula(self, k, x, a, b, n):
|
|
3018
|
+
r"""
|
|
3019
|
+
Evaluate ``self`` using an explicit formula.
|
|
3020
|
+
|
|
3021
|
+
EXAMPLES::
|
|
3022
|
+
|
|
3023
|
+
sage: # needs sage.symbolic
|
|
3024
|
+
sage: k, x, a, b, n = var('k,x,a,b,n')
|
|
3025
|
+
sage: Q2 = hahn.eval_formula(2, x, a, b, n).simplify_full()
|
|
3026
|
+
sage: Q2.coefficient(x^2).factor()
|
|
3027
|
+
(a + b + 4)*(a + b + 3)/((a + 2)*(a + 1)*(n - 1)*n)
|
|
3028
|
+
sage: Q2.coefficient(x).factor()
|
|
3029
|
+
-(2*a*n - a + b + 4*n)*(a + b + 3)/((a + 2)*(a + 1)*(n - 1)*n)
|
|
3030
|
+
sage: Q2(x=0)
|
|
3031
|
+
1
|
|
3032
|
+
"""
|
|
3033
|
+
P = rising_factorial
|
|
3034
|
+
return sum(P(-k, i) * P(k+a+b+1, i) * P(-x, i) / (P(a+1, i) * P(-n, i) * factorial(i))
|
|
3035
|
+
for i in range(k+1))
|
|
3036
|
+
|
|
3037
|
+
def _eval_(self, k, x, a, b, n, *args, **kwds):
|
|
3038
|
+
r"""
|
|
3039
|
+
Return an evaluation of the Hahn polynomial `Q_k(x; a, b, n)`.
|
|
3040
|
+
|
|
3041
|
+
EXAMPLES::
|
|
3042
|
+
|
|
3043
|
+
sage: k, x, a, b, n = var('k,x,a,b,n') # needs sage.symbolic
|
|
3044
|
+
sage: hahn(1, x, a, b, n).collect(x) # needs sage.symbolic
|
|
3045
|
+
-(a + b + 2)*x/((a + 1)*n) + 1
|
|
3046
|
+
sage: hahn(k, x, a, b, n) # needs sage.symbolic
|
|
3047
|
+
hypergeometric((-k, a + b + k + 1, -x), (a + 1, -n), 1)
|
|
3048
|
+
|
|
3049
|
+
sage: # needs sage.symbolic
|
|
3050
|
+
sage: k2_hypergeo = hahn(k, x, a, b, n)(k=2).simplify_hypergeometric()
|
|
3051
|
+
sage: bool(k2_hypergeo == hahn(2, x, a, b, n))
|
|
3052
|
+
True
|
|
3053
|
+
sage: k3_hypergeo = hahn(k, x, a, b, n)(k=3).simplify_hypergeometric()
|
|
3054
|
+
sage: bool(k3_hypergeo == hahn(3, x, a, b, n))
|
|
3055
|
+
True
|
|
3056
|
+
|
|
3057
|
+
sage: hahn(2, x, a, b, n, hold=True) # needs sage.symbolic
|
|
3058
|
+
hahn(2, x, a, b, n)
|
|
3059
|
+
"""
|
|
3060
|
+
if kwds.get('hold', False):
|
|
3061
|
+
return None
|
|
3062
|
+
if k not in ZZ or k < 0:
|
|
3063
|
+
from sage.functions.hypergeometric import hypergeometric
|
|
3064
|
+
return hypergeometric([-k, k+a+b+1, -x], [a+1, -n], 1)
|
|
3065
|
+
try:
|
|
3066
|
+
return self.eval_formula(k, x, a, b, n)
|
|
3067
|
+
except (TypeError, ValueError):
|
|
3068
|
+
return self.eval_recursive(k, x, a, b, n)
|
|
3069
|
+
|
|
3070
|
+
def eval_recursive(self, k, x, a, b, n, *args, **kwds):
|
|
3071
|
+
r"""
|
|
3072
|
+
Return the Hahn polynomial `Q_k(x; a, b, n)` using the
|
|
3073
|
+
recursive formula.
|
|
3074
|
+
|
|
3075
|
+
EXAMPLES::
|
|
3076
|
+
|
|
3077
|
+
sage: # needs sage.symbolic
|
|
3078
|
+
sage: x, a, b, n = var('x,a,b,n')
|
|
3079
|
+
sage: hahn.eval_recursive(0, x, a, b, n)
|
|
3080
|
+
1
|
|
3081
|
+
sage: hahn.eval_recursive(1, x, a, b, n)
|
|
3082
|
+
-(a + b + 2)*x/((a + 1)*n) + 1
|
|
3083
|
+
sage: bool(hahn(2, x, a, b, n) == hahn.eval_recursive(2, x, a, b, n))
|
|
3084
|
+
True
|
|
3085
|
+
sage: bool(hahn(3, x, a, b, n) == hahn.eval_recursive(3, x, a, b, n))
|
|
3086
|
+
True
|
|
3087
|
+
sage: bool(hahn(4, x, a, b, n) == hahn.eval_recursive(4, x, a, b, n))
|
|
3088
|
+
True
|
|
3089
|
+
sage: M = matrix([[-1/2, -1], [1, 0]]) # needs sage.modules
|
|
3090
|
+
sage: ret = hahn.eval_recursive(2, M, 1, 2, n).simplify_full().factor() # needs sage.modules
|
|
3091
|
+
sage: ret # needs sage.modules
|
|
3092
|
+
[1/4*(4*n^2 + 8*n - 19)/((n - 1)*n) 3/2*(4*n + 3)/((n - 1)*n)]
|
|
3093
|
+
[ -3/2*(4*n + 3)/((n - 1)*n) (n^2 - n - 7)/((n - 1)*n)]
|
|
3094
|
+
"""
|
|
3095
|
+
if k == 0:
|
|
3096
|
+
return parent(x).one()
|
|
3097
|
+
elif k == 1:
|
|
3098
|
+
return -(a+b+2) / ((a+1)*n) * x + 1
|
|
3099
|
+
A = (k+a+b) * (k+a) * (n-k+1) / ((2*k+a+b-1) * (2*k+a+b))
|
|
3100
|
+
C = (k-1) * (k+b-1) * (k+a+b+n) / ((2*k+a+b-2) * (2*k+a+b-1))
|
|
3101
|
+
Hm1 = (-x + A + C) * hahn.eval_recursive(k-1, x, a, b, n)
|
|
3102
|
+
Hm2 = C * hahn.eval_recursive(k-2, x, a, b, n)
|
|
3103
|
+
return (Hm1 - Hm2) / A
|
|
3104
|
+
|
|
3105
|
+
|
|
3106
|
+
hahn = Func_hahn()
|