passagemath-modules 10.6.31rc3__cp314-cp314-musllinux_1_2_x86_64.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.
Potentially problematic release.
This version of passagemath-modules might be problematic. Click here for more details.
- passagemath_modules-10.6.31rc3.dist-info/METADATA +281 -0
- passagemath_modules-10.6.31rc3.dist-info/RECORD +808 -0
- passagemath_modules-10.6.31rc3.dist-info/WHEEL +5 -0
- passagemath_modules-10.6.31rc3.dist-info/top_level.txt +2 -0
- passagemath_modules.libs/libgcc_s-0cd532bd.so.1 +0 -0
- passagemath_modules.libs/libgfortran-2c33b284.so.5.0.0 +0 -0
- passagemath_modules.libs/libgmp-0e7fc84e.so.10.5.0 +0 -0
- passagemath_modules.libs/libgsl-42cda06f.so.28.0.0 +0 -0
- passagemath_modules.libs/libmpc-d8ebe4b5.so.3.3.1 +0 -0
- passagemath_modules.libs/libmpfr-aaecbfc0.so.6.2.1 +0 -0
- passagemath_modules.libs/libopenblasp-r0-905cb27d.3.29.so +0 -0
- passagemath_modules.libs/libquadmath-bb76a5fc.so.0.0.0 +0 -0
- sage/algebras/all__sagemath_modules.py +20 -0
- sage/algebras/catalog.py +148 -0
- sage/algebras/clifford_algebra.py +3107 -0
- sage/algebras/clifford_algebra_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/algebras/clifford_algebra_element.pxd +16 -0
- sage/algebras/clifford_algebra_element.pyx +997 -0
- sage/algebras/commutative_dga.py +4252 -0
- sage/algebras/exterior_algebra_groebner.cpython-314-x86_64-linux-musl.so +0 -0
- sage/algebras/exterior_algebra_groebner.pxd +55 -0
- sage/algebras/exterior_algebra_groebner.pyx +727 -0
- sage/algebras/finite_dimensional_algebras/all.py +2 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py +1029 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pxd +12 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx +706 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_ideal.py +196 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py +255 -0
- sage/algebras/finite_gca.py +528 -0
- sage/algebras/group_algebra.py +232 -0
- sage/algebras/lie_algebras/abelian.py +197 -0
- sage/algebras/lie_algebras/affine_lie_algebra.py +1213 -0
- sage/algebras/lie_algebras/all.py +25 -0
- sage/algebras/lie_algebras/all__sagemath_modules.py +1 -0
- sage/algebras/lie_algebras/bch.py +177 -0
- sage/algebras/lie_algebras/bgg_dual_module.py +1184 -0
- sage/algebras/lie_algebras/bgg_resolution.py +232 -0
- sage/algebras/lie_algebras/center_uea.py +767 -0
- sage/algebras/lie_algebras/classical_lie_algebra.py +2516 -0
- sage/algebras/lie_algebras/examples.py +683 -0
- sage/algebras/lie_algebras/free_lie_algebra.py +973 -0
- sage/algebras/lie_algebras/heisenberg.py +820 -0
- sage/algebras/lie_algebras/lie_algebra.py +1562 -0
- sage/algebras/lie_algebras/lie_algebra_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/algebras/lie_algebras/lie_algebra_element.pxd +68 -0
- sage/algebras/lie_algebras/lie_algebra_element.pyx +2122 -0
- sage/algebras/lie_algebras/morphism.py +661 -0
- sage/algebras/lie_algebras/nilpotent_lie_algebra.py +457 -0
- sage/algebras/lie_algebras/onsager.py +1324 -0
- sage/algebras/lie_algebras/poincare_birkhoff_witt.py +816 -0
- sage/algebras/lie_algebras/quotient.py +462 -0
- sage/algebras/lie_algebras/rank_two_heisenberg_virasoro.py +355 -0
- sage/algebras/lie_algebras/representation.py +1040 -0
- sage/algebras/lie_algebras/structure_coefficients.py +459 -0
- sage/algebras/lie_algebras/subalgebra.py +967 -0
- sage/algebras/lie_algebras/symplectic_derivation.py +289 -0
- sage/algebras/lie_algebras/verma_module.py +1630 -0
- sage/algebras/lie_algebras/virasoro.py +1186 -0
- sage/algebras/octonion_algebra.cpython-314-x86_64-linux-musl.so +0 -0
- sage/algebras/octonion_algebra.pxd +20 -0
- sage/algebras/octonion_algebra.pyx +987 -0
- sage/algebras/orlik_solomon.py +907 -0
- sage/algebras/orlik_terao.py +779 -0
- sage/algebras/steenrod/all.py +7 -0
- sage/algebras/steenrod/steenrod_algebra.py +4258 -0
- sage/algebras/steenrod/steenrod_algebra_bases.py +1179 -0
- sage/algebras/steenrod/steenrod_algebra_misc.py +1167 -0
- sage/algebras/steenrod/steenrod_algebra_mult.py +954 -0
- sage/algebras/weyl_algebra.py +1126 -0
- sage/all__sagemath_modules.py +62 -0
- sage/calculus/all__sagemath_modules.py +19 -0
- sage/calculus/expr.py +205 -0
- sage/calculus/integration.cpython-314-x86_64-linux-musl.so +0 -0
- sage/calculus/integration.pyx +698 -0
- sage/calculus/interpolation.cpython-314-x86_64-linux-musl.so +0 -0
- sage/calculus/interpolation.pxd +13 -0
- sage/calculus/interpolation.pyx +387 -0
- sage/calculus/interpolators.cpython-314-x86_64-linux-musl.so +0 -0
- sage/calculus/interpolators.pyx +326 -0
- sage/calculus/ode.cpython-314-x86_64-linux-musl.so +0 -0
- sage/calculus/ode.pxd +5 -0
- sage/calculus/ode.pyx +610 -0
- sage/calculus/riemann.cpython-314-x86_64-linux-musl.so +0 -0
- sage/calculus/riemann.pyx +1521 -0
- sage/calculus/test_sympy.py +201 -0
- sage/calculus/transforms/all.py +7 -0
- sage/calculus/transforms/dft.py +844 -0
- sage/calculus/transforms/dwt.cpython-314-x86_64-linux-musl.so +0 -0
- sage/calculus/transforms/dwt.pxd +7 -0
- sage/calculus/transforms/dwt.pyx +160 -0
- sage/calculus/transforms/fft.cpython-314-x86_64-linux-musl.so +0 -0
- sage/calculus/transforms/fft.pxd +12 -0
- sage/calculus/transforms/fft.pyx +487 -0
- sage/calculus/wester.py +662 -0
- sage/coding/abstract_code.py +1108 -0
- sage/coding/ag_code.py +868 -0
- sage/coding/ag_code_decoders.cpython-314-x86_64-linux-musl.so +0 -0
- sage/coding/ag_code_decoders.pyx +2639 -0
- sage/coding/all.py +15 -0
- sage/coding/bch_code.py +494 -0
- sage/coding/binary_code.cpython-314-x86_64-linux-musl.so +0 -0
- sage/coding/binary_code.pxd +124 -0
- sage/coding/binary_code.pyx +4139 -0
- sage/coding/bounds_catalog.py +43 -0
- sage/coding/channel.py +819 -0
- sage/coding/channels_catalog.py +29 -0
- sage/coding/code_bounds.py +755 -0
- sage/coding/code_constructions.py +804 -0
- sage/coding/codes_catalog.py +111 -0
- sage/coding/cyclic_code.py +1329 -0
- sage/coding/databases.py +316 -0
- sage/coding/decoder.py +373 -0
- sage/coding/decoders_catalog.py +88 -0
- sage/coding/delsarte_bounds.py +709 -0
- sage/coding/encoder.py +390 -0
- sage/coding/encoders_catalog.py +64 -0
- sage/coding/extended_code.py +468 -0
- sage/coding/gabidulin_code.py +1058 -0
- sage/coding/golay_code.py +404 -0
- sage/coding/goppa_code.py +441 -0
- sage/coding/grs_code.py +2371 -0
- sage/coding/guava.py +107 -0
- sage/coding/guruswami_sudan/all.py +1 -0
- sage/coding/guruswami_sudan/gs_decoder.py +897 -0
- sage/coding/guruswami_sudan/interpolation.py +409 -0
- sage/coding/guruswami_sudan/utils.py +176 -0
- sage/coding/hamming_code.py +176 -0
- sage/coding/information_set_decoder.py +1032 -0
- sage/coding/kasami_codes.cpython-314-x86_64-linux-musl.so +0 -0
- sage/coding/kasami_codes.pyx +351 -0
- sage/coding/linear_code.py +3067 -0
- sage/coding/linear_code_no_metric.py +1354 -0
- sage/coding/linear_rank_metric.py +961 -0
- sage/coding/parity_check_code.py +353 -0
- sage/coding/punctured_code.py +719 -0
- sage/coding/reed_muller_code.py +999 -0
- sage/coding/self_dual_codes.py +942 -0
- sage/coding/source_coding/all.py +2 -0
- sage/coding/source_coding/huffman.py +553 -0
- sage/coding/subfield_subcode.py +423 -0
- sage/coding/two_weight_db.py +399 -0
- sage/combinat/all__sagemath_modules.py +7 -0
- sage/combinat/cartesian_product.py +347 -0
- sage/combinat/family.py +11 -0
- sage/combinat/free_module.py +1977 -0
- sage/combinat/root_system/all.py +147 -0
- sage/combinat/root_system/ambient_space.py +527 -0
- sage/combinat/root_system/associahedron.py +471 -0
- sage/combinat/root_system/braid_move_calculator.py +143 -0
- sage/combinat/root_system/braid_orbit.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/root_system/braid_orbit.pyx +144 -0
- sage/combinat/root_system/branching_rules.py +2301 -0
- sage/combinat/root_system/cartan_matrix.py +1245 -0
- sage/combinat/root_system/cartan_type.py +3069 -0
- sage/combinat/root_system/coxeter_group.py +162 -0
- sage/combinat/root_system/coxeter_matrix.py +1261 -0
- sage/combinat/root_system/coxeter_type.py +681 -0
- sage/combinat/root_system/dynkin_diagram.py +900 -0
- sage/combinat/root_system/extended_affine_weyl_group.py +2993 -0
- sage/combinat/root_system/fundamental_group.py +795 -0
- sage/combinat/root_system/hecke_algebra_representation.py +1203 -0
- sage/combinat/root_system/integrable_representations.py +1227 -0
- sage/combinat/root_system/non_symmetric_macdonald_polynomials.py +1965 -0
- sage/combinat/root_system/pieri_factors.py +1147 -0
- sage/combinat/root_system/plot.py +1615 -0
- sage/combinat/root_system/root_lattice_realization_algebras.py +1214 -0
- sage/combinat/root_system/root_lattice_realizations.py +4628 -0
- sage/combinat/root_system/root_space.py +487 -0
- sage/combinat/root_system/root_system.py +882 -0
- sage/combinat/root_system/type_A.py +348 -0
- sage/combinat/root_system/type_A_affine.py +227 -0
- sage/combinat/root_system/type_A_infinity.py +241 -0
- sage/combinat/root_system/type_B.py +347 -0
- sage/combinat/root_system/type_BC_affine.py +287 -0
- sage/combinat/root_system/type_B_affine.py +216 -0
- sage/combinat/root_system/type_C.py +317 -0
- sage/combinat/root_system/type_C_affine.py +188 -0
- sage/combinat/root_system/type_D.py +357 -0
- sage/combinat/root_system/type_D_affine.py +208 -0
- sage/combinat/root_system/type_E.py +641 -0
- sage/combinat/root_system/type_E_affine.py +231 -0
- sage/combinat/root_system/type_F.py +387 -0
- sage/combinat/root_system/type_F_affine.py +137 -0
- sage/combinat/root_system/type_G.py +293 -0
- sage/combinat/root_system/type_G_affine.py +132 -0
- sage/combinat/root_system/type_H.py +105 -0
- sage/combinat/root_system/type_I.py +110 -0
- sage/combinat/root_system/type_Q.py +150 -0
- sage/combinat/root_system/type_affine.py +509 -0
- sage/combinat/root_system/type_dual.py +704 -0
- sage/combinat/root_system/type_folded.py +301 -0
- sage/combinat/root_system/type_marked.py +748 -0
- sage/combinat/root_system/type_reducible.py +601 -0
- sage/combinat/root_system/type_relabel.py +730 -0
- sage/combinat/root_system/type_super_A.py +837 -0
- sage/combinat/root_system/weight_lattice_realizations.py +1188 -0
- sage/combinat/root_system/weight_space.py +639 -0
- sage/combinat/root_system/weyl_characters.py +2238 -0
- sage/crypto/__init__.py +4 -0
- sage/crypto/all.py +28 -0
- sage/crypto/block_cipher/all.py +7 -0
- sage/crypto/block_cipher/des.py +1065 -0
- sage/crypto/block_cipher/miniaes.py +2171 -0
- sage/crypto/block_cipher/present.py +909 -0
- sage/crypto/block_cipher/sdes.py +1527 -0
- sage/crypto/boolean_function.cpython-314-x86_64-linux-musl.so +0 -0
- sage/crypto/boolean_function.pxd +10 -0
- sage/crypto/boolean_function.pyx +1487 -0
- sage/crypto/cipher.py +78 -0
- sage/crypto/classical.py +3668 -0
- sage/crypto/classical_cipher.py +569 -0
- sage/crypto/cryptosystem.py +387 -0
- sage/crypto/key_exchange/all.py +7 -0
- sage/crypto/key_exchange/catalog.py +24 -0
- sage/crypto/key_exchange/diffie_hellman.py +323 -0
- sage/crypto/key_exchange/key_exchange_scheme.py +107 -0
- sage/crypto/lattice.py +312 -0
- sage/crypto/lfsr.py +295 -0
- sage/crypto/lwe.py +840 -0
- sage/crypto/mq/__init__.py +4 -0
- sage/crypto/mq/mpolynomialsystemgenerator.py +204 -0
- sage/crypto/mq/rijndael_gf.py +2345 -0
- sage/crypto/mq/sbox.py +7 -0
- sage/crypto/mq/sr.py +3344 -0
- sage/crypto/public_key/all.py +5 -0
- sage/crypto/public_key/blum_goldwasser.py +776 -0
- sage/crypto/sbox.cpython-314-x86_64-linux-musl.so +0 -0
- sage/crypto/sbox.pyx +2090 -0
- sage/crypto/sboxes.py +2090 -0
- sage/crypto/stream.py +390 -0
- sage/crypto/stream_cipher.py +297 -0
- sage/crypto/util.py +519 -0
- sage/ext/all__sagemath_modules.py +1 -0
- sage/ext/interpreters/__init__.py +1 -0
- sage/ext/interpreters/all__sagemath_modules.py +2 -0
- sage/ext/interpreters/wrapper_cc.cpython-314-x86_64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_cc.pxd +30 -0
- sage/ext/interpreters/wrapper_cc.pyx +252 -0
- sage/ext/interpreters/wrapper_cdf.cpython-314-x86_64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_cdf.pxd +26 -0
- sage/ext/interpreters/wrapper_cdf.pyx +245 -0
- sage/ext/interpreters/wrapper_rdf.cpython-314-x86_64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_rdf.pxd +23 -0
- sage/ext/interpreters/wrapper_rdf.pyx +221 -0
- sage/ext/interpreters/wrapper_rr.cpython-314-x86_64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_rr.pxd +28 -0
- sage/ext/interpreters/wrapper_rr.pyx +335 -0
- sage/geometry/all__sagemath_modules.py +5 -0
- sage/geometry/toric_lattice.py +1745 -0
- sage/geometry/toric_lattice_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/geometry/toric_lattice_element.pyx +432 -0
- sage/groups/abelian_gps/abelian_group.py +1925 -0
- sage/groups/abelian_gps/abelian_group_element.py +164 -0
- sage/groups/abelian_gps/all__sagemath_modules.py +5 -0
- sage/groups/abelian_gps/dual_abelian_group.py +421 -0
- sage/groups/abelian_gps/dual_abelian_group_element.py +179 -0
- sage/groups/abelian_gps/element_base.py +341 -0
- sage/groups/abelian_gps/values.py +488 -0
- sage/groups/additive_abelian/additive_abelian_group.py +476 -0
- sage/groups/additive_abelian/additive_abelian_wrapper.py +857 -0
- sage/groups/additive_abelian/all.py +4 -0
- sage/groups/additive_abelian/qmodnz.py +231 -0
- sage/groups/additive_abelian/qmodnz_element.py +349 -0
- sage/groups/affine_gps/affine_group.py +535 -0
- sage/groups/affine_gps/all.py +1 -0
- sage/groups/affine_gps/catalog.py +17 -0
- sage/groups/affine_gps/euclidean_group.py +246 -0
- sage/groups/affine_gps/group_element.py +562 -0
- sage/groups/all__sagemath_modules.py +12 -0
- sage/groups/galois_group.py +479 -0
- sage/groups/matrix_gps/all.py +4 -0
- sage/groups/matrix_gps/all__sagemath_modules.py +13 -0
- sage/groups/matrix_gps/catalog.py +26 -0
- sage/groups/matrix_gps/coxeter_group.py +927 -0
- sage/groups/matrix_gps/finitely_generated.py +487 -0
- sage/groups/matrix_gps/group_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/groups/matrix_gps/group_element.pxd +11 -0
- sage/groups/matrix_gps/group_element.pyx +431 -0
- sage/groups/matrix_gps/linear.py +440 -0
- sage/groups/matrix_gps/matrix_group.py +617 -0
- sage/groups/matrix_gps/named_group.py +296 -0
- sage/groups/matrix_gps/orthogonal.py +544 -0
- sage/groups/matrix_gps/symplectic.py +251 -0
- sage/groups/matrix_gps/unitary.py +436 -0
- sage/groups/misc_gps/all__sagemath_modules.py +1 -0
- sage/groups/misc_gps/argument_groups.py +1905 -0
- sage/groups/misc_gps/imaginary_groups.py +479 -0
- sage/groups/perm_gps/all__sagemath_modules.py +1 -0
- sage/groups/perm_gps/partn_ref/all__sagemath_modules.py +1 -0
- sage/groups/perm_gps/partn_ref/refinement_binary.cpython-314-x86_64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_binary.pxd +41 -0
- sage/groups/perm_gps/partn_ref/refinement_binary.pyx +1167 -0
- sage/groups/perm_gps/partn_ref/refinement_matrices.cpython-314-x86_64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_matrices.pxd +31 -0
- sage/groups/perm_gps/partn_ref/refinement_matrices.pyx +385 -0
- sage/homology/algebraic_topological_model.py +595 -0
- sage/homology/all.py +2 -0
- sage/homology/all__sagemath_modules.py +8 -0
- sage/homology/chain_complex.py +2148 -0
- sage/homology/chain_complex_homspace.py +165 -0
- sage/homology/chain_complex_morphism.py +629 -0
- sage/homology/chain_homotopy.py +604 -0
- sage/homology/chains.py +653 -0
- sage/homology/free_resolution.py +923 -0
- sage/homology/graded_resolution.py +567 -0
- sage/homology/hochschild_complex.py +756 -0
- sage/homology/homology_group.py +188 -0
- sage/homology/homology_morphism.py +422 -0
- sage/homology/homology_vector_space_with_basis.py +1454 -0
- sage/homology/koszul_complex.py +169 -0
- sage/homology/matrix_utils.py +205 -0
- sage/libs/all__sagemath_modules.py +1 -0
- sage/libs/gsl/__init__.py +1 -0
- sage/libs/gsl/airy.pxd +56 -0
- sage/libs/gsl/all.pxd +66 -0
- sage/libs/gsl/array.cpython-314-x86_64-linux-musl.so +0 -0
- sage/libs/gsl/array.pxd +5 -0
- sage/libs/gsl/array.pyx +102 -0
- sage/libs/gsl/bessel.pxd +208 -0
- sage/libs/gsl/blas.pxd +116 -0
- sage/libs/gsl/blas_types.pxd +34 -0
- sage/libs/gsl/block.pxd +52 -0
- sage/libs/gsl/chebyshev.pxd +37 -0
- sage/libs/gsl/clausen.pxd +12 -0
- sage/libs/gsl/combination.pxd +47 -0
- sage/libs/gsl/complex.pxd +151 -0
- sage/libs/gsl/coulomb.pxd +30 -0
- sage/libs/gsl/coupling.pxd +21 -0
- sage/libs/gsl/dawson.pxd +12 -0
- sage/libs/gsl/debye.pxd +24 -0
- sage/libs/gsl/dilog.pxd +14 -0
- sage/libs/gsl/eigen.pxd +46 -0
- sage/libs/gsl/elementary.pxd +12 -0
- sage/libs/gsl/ellint.pxd +48 -0
- sage/libs/gsl/elljac.pxd +8 -0
- sage/libs/gsl/erf.pxd +32 -0
- sage/libs/gsl/errno.pxd +26 -0
- sage/libs/gsl/exp.pxd +44 -0
- sage/libs/gsl/expint.pxd +44 -0
- sage/libs/gsl/fermi_dirac.pxd +44 -0
- sage/libs/gsl/fft.pxd +121 -0
- sage/libs/gsl/fit.pxd +50 -0
- sage/libs/gsl/gamma.pxd +94 -0
- sage/libs/gsl/gegenbauer.pxd +26 -0
- sage/libs/gsl/histogram.pxd +176 -0
- sage/libs/gsl/hyperg.pxd +52 -0
- sage/libs/gsl/integration.pxd +69 -0
- sage/libs/gsl/interp.pxd +109 -0
- sage/libs/gsl/laguerre.pxd +24 -0
- sage/libs/gsl/lambert.pxd +16 -0
- sage/libs/gsl/legendre.pxd +90 -0
- sage/libs/gsl/linalg.pxd +185 -0
- sage/libs/gsl/log.pxd +26 -0
- sage/libs/gsl/math.pxd +43 -0
- sage/libs/gsl/matrix.pxd +143 -0
- sage/libs/gsl/matrix_complex.pxd +130 -0
- sage/libs/gsl/min.pxd +67 -0
- sage/libs/gsl/monte.pxd +56 -0
- sage/libs/gsl/ntuple.pxd +32 -0
- sage/libs/gsl/odeiv.pxd +70 -0
- sage/libs/gsl/permutation.pxd +78 -0
- sage/libs/gsl/poly.pxd +40 -0
- sage/libs/gsl/pow_int.pxd +12 -0
- sage/libs/gsl/psi.pxd +28 -0
- sage/libs/gsl/qrng.pxd +29 -0
- sage/libs/gsl/random.pxd +257 -0
- sage/libs/gsl/rng.pxd +100 -0
- sage/libs/gsl/roots.pxd +72 -0
- sage/libs/gsl/sort.pxd +36 -0
- sage/libs/gsl/statistics.pxd +59 -0
- sage/libs/gsl/sum.pxd +55 -0
- sage/libs/gsl/synchrotron.pxd +16 -0
- sage/libs/gsl/transport.pxd +24 -0
- sage/libs/gsl/trig.pxd +58 -0
- sage/libs/gsl/types.pxd +137 -0
- sage/libs/gsl/vector.pxd +101 -0
- sage/libs/gsl/vector_complex.pxd +83 -0
- sage/libs/gsl/wavelet.pxd +49 -0
- sage/libs/gsl/zeta.pxd +28 -0
- sage/libs/mpc/__init__.pxd +114 -0
- sage/libs/mpc/types.pxd +28 -0
- sage/libs/mpfr/__init__.pxd +299 -0
- sage/libs/mpfr/types.pxd +26 -0
- sage/libs/mpmath/__init__.py +1 -0
- sage/libs/mpmath/all.py +27 -0
- sage/libs/mpmath/all__sagemath_modules.py +1 -0
- sage/libs/mpmath/utils.cpython-314-x86_64-linux-musl.so +0 -0
- sage/libs/mpmath/utils.pxd +4 -0
- sage/libs/mpmath/utils.pyx +319 -0
- sage/matrix/action.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/action.pxd +26 -0
- sage/matrix/action.pyx +596 -0
- sage/matrix/all.py +9 -0
- sage/matrix/args.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/args.pxd +144 -0
- sage/matrix/args.pyx +1668 -0
- sage/matrix/benchmark.py +1258 -0
- sage/matrix/berlekamp_massey.py +95 -0
- sage/matrix/compute_J_ideal.py +926 -0
- sage/matrix/constructor.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/constructor.pyx +750 -0
- sage/matrix/docs.py +430 -0
- sage/matrix/echelon_matrix.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/echelon_matrix.pyx +155 -0
- sage/matrix/matrix.pxd +2 -0
- sage/matrix/matrix0.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix0.pxd +68 -0
- sage/matrix/matrix0.pyx +6324 -0
- sage/matrix/matrix1.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix1.pxd +8 -0
- sage/matrix/matrix1.pyx +2851 -0
- sage/matrix/matrix2.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix2.pxd +25 -0
- sage/matrix/matrix2.pyx +20181 -0
- sage/matrix/matrix_cdv.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_cdv.pxd +4 -0
- sage/matrix/matrix_cdv.pyx +93 -0
- sage/matrix/matrix_complex_double_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_complex_double_dense.pxd +5 -0
- sage/matrix/matrix_complex_double_dense.pyx +98 -0
- sage/matrix/matrix_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_dense.pxd +5 -0
- sage/matrix/matrix_dense.pyx +343 -0
- sage/matrix/matrix_domain_dense.pxd +5 -0
- sage/matrix/matrix_domain_sparse.pxd +5 -0
- sage/matrix/matrix_double_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_double_dense.pxd +7 -0
- sage/matrix/matrix_double_dense.pyx +3906 -0
- sage/matrix/matrix_double_sparse.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_double_sparse.pxd +6 -0
- sage/matrix/matrix_double_sparse.pyx +248 -0
- sage/matrix/matrix_generic_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_generic_dense.pxd +7 -0
- sage/matrix/matrix_generic_dense.pyx +354 -0
- sage/matrix/matrix_generic_sparse.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_generic_sparse.pxd +7 -0
- sage/matrix/matrix_generic_sparse.pyx +461 -0
- sage/matrix/matrix_laurent_mpolynomial_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_laurent_mpolynomial_dense.pxd +5 -0
- sage/matrix/matrix_laurent_mpolynomial_dense.pyx +115 -0
- sage/matrix/matrix_misc.py +313 -0
- sage/matrix/matrix_numpy_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_numpy_dense.pxd +14 -0
- sage/matrix/matrix_numpy_dense.pyx +450 -0
- sage/matrix/matrix_numpy_integer_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_numpy_integer_dense.pxd +7 -0
- sage/matrix/matrix_numpy_integer_dense.pyx +59 -0
- sage/matrix/matrix_polynomial_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_polynomial_dense.pxd +5 -0
- sage/matrix/matrix_polynomial_dense.pyx +5341 -0
- sage/matrix/matrix_real_double_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_real_double_dense.pxd +7 -0
- sage/matrix/matrix_real_double_dense.pyx +122 -0
- sage/matrix/matrix_space.py +2848 -0
- sage/matrix/matrix_sparse.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_sparse.pxd +5 -0
- sage/matrix/matrix_sparse.pyx +1222 -0
- sage/matrix/matrix_window.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_window.pxd +37 -0
- sage/matrix/matrix_window.pyx +242 -0
- sage/matrix/misc_mpfr.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/misc_mpfr.pyx +80 -0
- sage/matrix/operation_table.py +1182 -0
- sage/matrix/special.py +3666 -0
- sage/matrix/strassen.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/strassen.pyx +851 -0
- sage/matrix/symplectic_basis.py +541 -0
- sage/matrix/template.pxd +6 -0
- sage/matrix/tests.py +71 -0
- sage/matroids/advanced.py +77 -0
- sage/matroids/all.py +13 -0
- sage/matroids/basis_exchange_matroid.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matroids/basis_exchange_matroid.pxd +96 -0
- sage/matroids/basis_exchange_matroid.pyx +2344 -0
- sage/matroids/basis_matroid.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matroids/basis_matroid.pxd +45 -0
- sage/matroids/basis_matroid.pyx +1217 -0
- sage/matroids/catalog.py +44 -0
- sage/matroids/chow_ring.py +473 -0
- sage/matroids/chow_ring_ideal.py +849 -0
- sage/matroids/circuit_closures_matroid.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matroids/circuit_closures_matroid.pxd +16 -0
- sage/matroids/circuit_closures_matroid.pyx +559 -0
- sage/matroids/circuits_matroid.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matroids/circuits_matroid.pxd +38 -0
- sage/matroids/circuits_matroid.pyx +947 -0
- sage/matroids/constructor.py +1086 -0
- sage/matroids/database_collections.py +365 -0
- sage/matroids/database_matroids.py +5338 -0
- sage/matroids/dual_matroid.py +583 -0
- sage/matroids/extension.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matroids/extension.pxd +34 -0
- sage/matroids/extension.pyx +519 -0
- sage/matroids/flats_matroid.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matroids/flats_matroid.pxd +28 -0
- sage/matroids/flats_matroid.pyx +715 -0
- sage/matroids/gammoid.py +600 -0
- sage/matroids/graphic_matroid.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matroids/graphic_matroid.pxd +39 -0
- sage/matroids/graphic_matroid.pyx +2024 -0
- sage/matroids/lean_matrix.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matroids/lean_matrix.pxd +126 -0
- sage/matroids/lean_matrix.pyx +3667 -0
- sage/matroids/linear_matroid.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matroids/linear_matroid.pxd +180 -0
- sage/matroids/linear_matroid.pyx +6649 -0
- sage/matroids/matroid.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matroids/matroid.pxd +243 -0
- sage/matroids/matroid.pyx +8759 -0
- sage/matroids/matroids_catalog.py +190 -0
- sage/matroids/matroids_plot_helpers.py +890 -0
- sage/matroids/minor_matroid.py +480 -0
- sage/matroids/minorfix.h +9 -0
- sage/matroids/named_matroids.py +5 -0
- sage/matroids/rank_matroid.py +268 -0
- sage/matroids/set_system.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matroids/set_system.pxd +38 -0
- sage/matroids/set_system.pyx +800 -0
- sage/matroids/transversal_matroid.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matroids/transversal_matroid.pxd +14 -0
- sage/matroids/transversal_matroid.pyx +893 -0
- sage/matroids/union_matroid.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matroids/union_matroid.pxd +20 -0
- sage/matroids/union_matroid.pyx +331 -0
- sage/matroids/unpickling.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matroids/unpickling.pyx +843 -0
- sage/matroids/utilities.py +809 -0
- sage/misc/all__sagemath_modules.py +20 -0
- sage/misc/c3.cpython-314-x86_64-linux-musl.so +0 -0
- sage/misc/c3.pyx +238 -0
- sage/misc/compat.py +87 -0
- sage/misc/element_with_label.py +173 -0
- sage/misc/func_persist.py +79 -0
- sage/misc/pickle_old.cpython-314-x86_64-linux-musl.so +0 -0
- sage/misc/pickle_old.pyx +19 -0
- sage/misc/proof.py +7 -0
- sage/misc/replace_dot_all.py +472 -0
- sage/misc/sagedoc_conf.py +168 -0
- sage/misc/sphinxify.py +167 -0
- sage/misc/test_class_pickling.py +85 -0
- sage/modules/all.py +42 -0
- sage/modules/complex_double_vector.py +25 -0
- sage/modules/diamond_cutting.py +380 -0
- sage/modules/fg_pid/all.py +1 -0
- sage/modules/fg_pid/fgp_element.py +456 -0
- sage/modules/fg_pid/fgp_module.py +2091 -0
- sage/modules/fg_pid/fgp_morphism.py +550 -0
- sage/modules/filtered_vector_space.py +1271 -0
- sage/modules/finite_submodule_iter.cpython-314-x86_64-linux-musl.so +0 -0
- sage/modules/finite_submodule_iter.pxd +27 -0
- sage/modules/finite_submodule_iter.pyx +452 -0
- sage/modules/fp_graded/all.py +1 -0
- sage/modules/fp_graded/element.py +346 -0
- sage/modules/fp_graded/free_element.py +298 -0
- sage/modules/fp_graded/free_homspace.py +53 -0
- sage/modules/fp_graded/free_module.py +1060 -0
- sage/modules/fp_graded/free_morphism.py +217 -0
- sage/modules/fp_graded/homspace.py +563 -0
- sage/modules/fp_graded/module.py +1340 -0
- sage/modules/fp_graded/morphism.py +1990 -0
- sage/modules/fp_graded/steenrod/all.py +1 -0
- sage/modules/fp_graded/steenrod/homspace.py +65 -0
- sage/modules/fp_graded/steenrod/module.py +477 -0
- sage/modules/fp_graded/steenrod/morphism.py +404 -0
- sage/modules/fp_graded/steenrod/profile.py +241 -0
- sage/modules/free_module.py +8447 -0
- sage/modules/free_module_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/modules/free_module_element.pxd +22 -0
- sage/modules/free_module_element.pyx +5445 -0
- sage/modules/free_module_homspace.py +369 -0
- sage/modules/free_module_integer.py +896 -0
- sage/modules/free_module_morphism.py +823 -0
- sage/modules/free_module_pseudohomspace.py +352 -0
- sage/modules/free_module_pseudomorphism.py +578 -0
- sage/modules/free_quadratic_module.py +1706 -0
- sage/modules/free_quadratic_module_integer_symmetric.py +1790 -0
- sage/modules/matrix_morphism.py +1745 -0
- sage/modules/misc.py +103 -0
- sage/modules/module_functors.py +192 -0
- sage/modules/multi_filtered_vector_space.py +719 -0
- sage/modules/ore_module.py +2208 -0
- sage/modules/ore_module_element.py +178 -0
- sage/modules/ore_module_homspace.py +147 -0
- sage/modules/ore_module_morphism.py +968 -0
- sage/modules/quotient_module.py +699 -0
- sage/modules/real_double_vector.py +22 -0
- sage/modules/submodule.py +255 -0
- sage/modules/tensor_operations.py +567 -0
- sage/modules/torsion_quadratic_module.py +1352 -0
- sage/modules/tutorial_free_modules.py +248 -0
- sage/modules/vector_complex_double_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/modules/vector_complex_double_dense.pxd +6 -0
- sage/modules/vector_complex_double_dense.pyx +117 -0
- sage/modules/vector_double_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/modules/vector_double_dense.pxd +6 -0
- sage/modules/vector_double_dense.pyx +604 -0
- sage/modules/vector_integer_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/modules/vector_integer_dense.pxd +15 -0
- sage/modules/vector_integer_dense.pyx +361 -0
- sage/modules/vector_integer_sparse.cpython-314-x86_64-linux-musl.so +0 -0
- sage/modules/vector_integer_sparse.pxd +29 -0
- sage/modules/vector_integer_sparse.pyx +406 -0
- sage/modules/vector_modn_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/modules/vector_modn_dense.pxd +12 -0
- sage/modules/vector_modn_dense.pyx +394 -0
- sage/modules/vector_modn_sparse.cpython-314-x86_64-linux-musl.so +0 -0
- sage/modules/vector_modn_sparse.pxd +21 -0
- sage/modules/vector_modn_sparse.pyx +298 -0
- sage/modules/vector_numpy_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/modules/vector_numpy_dense.pxd +15 -0
- sage/modules/vector_numpy_dense.pyx +304 -0
- sage/modules/vector_numpy_integer_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/modules/vector_numpy_integer_dense.pxd +7 -0
- sage/modules/vector_numpy_integer_dense.pyx +54 -0
- sage/modules/vector_rational_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/modules/vector_rational_dense.pxd +15 -0
- sage/modules/vector_rational_dense.pyx +387 -0
- sage/modules/vector_rational_sparse.cpython-314-x86_64-linux-musl.so +0 -0
- sage/modules/vector_rational_sparse.pxd +30 -0
- sage/modules/vector_rational_sparse.pyx +413 -0
- sage/modules/vector_real_double_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/modules/vector_real_double_dense.pxd +6 -0
- sage/modules/vector_real_double_dense.pyx +126 -0
- sage/modules/vector_space_homspace.py +430 -0
- sage/modules/vector_space_morphism.py +989 -0
- sage/modules/with_basis/all.py +15 -0
- sage/modules/with_basis/cell_module.py +494 -0
- sage/modules/with_basis/indexed_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/modules/with_basis/indexed_element.pxd +13 -0
- sage/modules/with_basis/indexed_element.pyx +1058 -0
- sage/modules/with_basis/invariant.py +1075 -0
- sage/modules/with_basis/morphism.py +1636 -0
- sage/modules/with_basis/representation.py +2939 -0
- sage/modules/with_basis/subquotient.py +685 -0
- sage/numerical/all__sagemath_modules.py +6 -0
- sage/numerical/gauss_legendre.cpython-314-x86_64-linux-musl.so +0 -0
- sage/numerical/gauss_legendre.pyx +381 -0
- sage/numerical/optimize.py +910 -0
- sage/probability/all.py +10 -0
- sage/probability/probability_distribution.cpython-314-x86_64-linux-musl.so +0 -0
- sage/probability/probability_distribution.pyx +1242 -0
- sage/probability/random_variable.py +411 -0
- sage/quadratic_forms/all.py +4 -0
- sage/quadratic_forms/all__sagemath_modules.py +15 -0
- sage/quadratic_forms/binary_qf.py +2042 -0
- sage/quadratic_forms/bqf_class_group.py +748 -0
- sage/quadratic_forms/constructions.py +93 -0
- sage/quadratic_forms/count_local_2.cpython-314-x86_64-linux-musl.so +0 -0
- sage/quadratic_forms/count_local_2.pyx +365 -0
- sage/quadratic_forms/extras.py +195 -0
- sage/quadratic_forms/quadratic_form.py +1753 -0
- sage/quadratic_forms/quadratic_form__count_local_2.py +221 -0
- sage/quadratic_forms/quadratic_form__equivalence_testing.py +708 -0
- sage/quadratic_forms/quadratic_form__evaluate.cpython-314-x86_64-linux-musl.so +0 -0
- sage/quadratic_forms/quadratic_form__evaluate.pyx +139 -0
- sage/quadratic_forms/quadratic_form__local_density_congruence.py +977 -0
- sage/quadratic_forms/quadratic_form__local_field_invariants.py +1072 -0
- sage/quadratic_forms/quadratic_form__neighbors.py +424 -0
- sage/quadratic_forms/quadratic_form__reduction_theory.py +488 -0
- sage/quadratic_forms/quadratic_form__split_local_covering.py +416 -0
- sage/quadratic_forms/quadratic_form__ternary_Tornaria.py +657 -0
- sage/quadratic_forms/quadratic_form__theta.py +352 -0
- sage/quadratic_forms/quadratic_form__variable_substitutions.py +370 -0
- sage/quadratic_forms/random_quadraticform.py +209 -0
- sage/quadratic_forms/ternary.cpython-314-x86_64-linux-musl.so +0 -0
- sage/quadratic_forms/ternary.pyx +1154 -0
- sage/quadratic_forms/ternary_qf.py +2027 -0
- sage/rings/all__sagemath_modules.py +28 -0
- sage/rings/asymptotic/all__sagemath_modules.py +1 -0
- sage/rings/asymptotic/misc.py +1252 -0
- sage/rings/cc.py +4 -0
- sage/rings/cfinite_sequence.py +1306 -0
- sage/rings/complex_conversion.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/complex_conversion.pxd +8 -0
- sage/rings/complex_conversion.pyx +23 -0
- sage/rings/complex_double.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/complex_double.pxd +21 -0
- sage/rings/complex_double.pyx +2654 -0
- sage/rings/complex_mpc.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/complex_mpc.pxd +21 -0
- sage/rings/complex_mpc.pyx +2576 -0
- sage/rings/complex_mpfr.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/complex_mpfr.pxd +18 -0
- sage/rings/complex_mpfr.pyx +3602 -0
- sage/rings/derivation.py +2334 -0
- sage/rings/finite_rings/all__sagemath_modules.py +1 -0
- sage/rings/finite_rings/maps_finite_field.py +191 -0
- sage/rings/function_field/all__sagemath_modules.py +8 -0
- sage/rings/function_field/derivations.py +102 -0
- sage/rings/function_field/derivations_rational.py +132 -0
- sage/rings/function_field/differential.py +853 -0
- sage/rings/function_field/divisor.py +1107 -0
- sage/rings/function_field/drinfeld_modules/action.py +199 -0
- sage/rings/function_field/drinfeld_modules/all.py +1 -0
- sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py +673 -0
- sage/rings/function_field/drinfeld_modules/drinfeld_module.py +2087 -0
- sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py +1131 -0
- sage/rings/function_field/drinfeld_modules/homset.py +420 -0
- sage/rings/function_field/drinfeld_modules/morphism.py +820 -0
- sage/rings/function_field/hermite_form_polynomial.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/function_field/hermite_form_polynomial.pyx +188 -0
- sage/rings/function_field/khuri_makdisi.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/function_field/khuri_makdisi.pyx +935 -0
- sage/rings/invariants/all.py +4 -0
- sage/rings/invariants/invariant_theory.py +4597 -0
- sage/rings/invariants/reconstruction.py +395 -0
- sage/rings/polynomial/all__sagemath_modules.py +17 -0
- sage/rings/polynomial/integer_valued_polynomials.py +1230 -0
- sage/rings/polynomial/laurent_polynomial_mpair.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/polynomial/laurent_polynomial_mpair.pxd +15 -0
- sage/rings/polynomial/laurent_polynomial_mpair.pyx +2023 -0
- sage/rings/polynomial/ore_function_element.py +952 -0
- sage/rings/polynomial/ore_function_field.py +1028 -0
- sage/rings/polynomial/ore_polynomial_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/polynomial/ore_polynomial_element.pxd +48 -0
- sage/rings/polynomial/ore_polynomial_element.pyx +3145 -0
- sage/rings/polynomial/ore_polynomial_ring.py +1334 -0
- sage/rings/polynomial/polynomial_real_mpfr_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/polynomial/polynomial_real_mpfr_dense.pyx +788 -0
- sage/rings/polynomial/q_integer_valued_polynomials.py +1264 -0
- sage/rings/polynomial/skew_polynomial_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/polynomial/skew_polynomial_element.pxd +9 -0
- sage/rings/polynomial/skew_polynomial_element.pyx +684 -0
- sage/rings/polynomial/skew_polynomial_finite_field.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/polynomial/skew_polynomial_finite_field.pxd +19 -0
- sage/rings/polynomial/skew_polynomial_finite_field.pyx +1093 -0
- sage/rings/polynomial/skew_polynomial_finite_order.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/polynomial/skew_polynomial_finite_order.pxd +10 -0
- sage/rings/polynomial/skew_polynomial_finite_order.pyx +567 -0
- sage/rings/polynomial/skew_polynomial_ring.py +908 -0
- sage/rings/real_double_element_gsl.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/real_double_element_gsl.pxd +8 -0
- sage/rings/real_double_element_gsl.pyx +794 -0
- sage/rings/real_field.py +58 -0
- sage/rings/real_mpfr.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/real_mpfr.pxd +29 -0
- sage/rings/real_mpfr.pyx +6122 -0
- sage/rings/ring_extension.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/ring_extension.pxd +42 -0
- sage/rings/ring_extension.pyx +2779 -0
- sage/rings/ring_extension_conversion.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/ring_extension_conversion.pxd +16 -0
- sage/rings/ring_extension_conversion.pyx +462 -0
- sage/rings/ring_extension_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/ring_extension_element.pxd +21 -0
- sage/rings/ring_extension_element.pyx +1635 -0
- sage/rings/ring_extension_homset.py +64 -0
- sage/rings/ring_extension_morphism.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/ring_extension_morphism.pxd +35 -0
- sage/rings/ring_extension_morphism.pyx +920 -0
- sage/schemes/all__sagemath_modules.py +1 -0
- sage/schemes/projective/all__sagemath_modules.py +1 -0
- sage/schemes/projective/coherent_sheaf.py +300 -0
- sage/schemes/projective/cohomology.py +510 -0
- sage/stats/all.py +15 -0
- sage/stats/basic_stats.py +489 -0
- sage/stats/distributions/all.py +7 -0
- sage/stats/distributions/catalog.py +34 -0
- sage/stats/distributions/dgs.h +50 -0
- sage/stats/distributions/dgs.pxd +111 -0
- sage/stats/distributions/dgs_bern.h +400 -0
- sage/stats/distributions/dgs_gauss.h +614 -0
- sage/stats/distributions/dgs_misc.h +104 -0
- sage/stats/distributions/discrete_gaussian_integer.cpython-314-x86_64-linux-musl.so +0 -0
- sage/stats/distributions/discrete_gaussian_integer.pxd +14 -0
- sage/stats/distributions/discrete_gaussian_integer.pyx +498 -0
- sage/stats/distributions/discrete_gaussian_lattice.py +908 -0
- sage/stats/distributions/discrete_gaussian_polynomial.py +141 -0
- sage/stats/hmm/all.py +15 -0
- sage/stats/hmm/chmm.cpython-314-x86_64-linux-musl.so +0 -0
- sage/stats/hmm/chmm.pyx +1595 -0
- sage/stats/hmm/distributions.cpython-314-x86_64-linux-musl.so +0 -0
- sage/stats/hmm/distributions.pxd +29 -0
- sage/stats/hmm/distributions.pyx +531 -0
- sage/stats/hmm/hmm.cpython-314-x86_64-linux-musl.so +0 -0
- sage/stats/hmm/hmm.pxd +17 -0
- sage/stats/hmm/hmm.pyx +1388 -0
- sage/stats/hmm/util.cpython-314-x86_64-linux-musl.so +0 -0
- sage/stats/hmm/util.pxd +7 -0
- sage/stats/hmm/util.pyx +165 -0
- sage/stats/intlist.cpython-314-x86_64-linux-musl.so +0 -0
- sage/stats/intlist.pxd +14 -0
- sage/stats/intlist.pyx +588 -0
- sage/stats/r.py +49 -0
- sage/stats/time_series.cpython-314-x86_64-linux-musl.so +0 -0
- sage/stats/time_series.pxd +6 -0
- sage/stats/time_series.pyx +2546 -0
- sage/tensor/all.py +2 -0
- sage/tensor/modules/all.py +8 -0
- sage/tensor/modules/alternating_contr_tensor.py +761 -0
- sage/tensor/modules/comp.py +5598 -0
- sage/tensor/modules/ext_pow_free_module.py +824 -0
- sage/tensor/modules/finite_rank_free_module.py +3589 -0
- sage/tensor/modules/format_utilities.py +333 -0
- sage/tensor/modules/free_module_alt_form.py +858 -0
- sage/tensor/modules/free_module_automorphism.py +1207 -0
- sage/tensor/modules/free_module_basis.py +1074 -0
- sage/tensor/modules/free_module_element.py +284 -0
- sage/tensor/modules/free_module_homset.py +652 -0
- sage/tensor/modules/free_module_linear_group.py +564 -0
- sage/tensor/modules/free_module_morphism.py +1581 -0
- sage/tensor/modules/free_module_tensor.py +3289 -0
- sage/tensor/modules/reflexive_module.py +386 -0
- sage/tensor/modules/tensor_free_module.py +780 -0
- sage/tensor/modules/tensor_free_submodule.py +538 -0
- sage/tensor/modules/tensor_free_submodule_basis.py +140 -0
- sage/tensor/modules/tensor_with_indices.py +1043 -0
|
@@ -0,0 +1,1521 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-modules
|
|
2
|
+
# sage.doctest: needs numpy sage.symbolic
|
|
3
|
+
"""
|
|
4
|
+
Riemann Mapping
|
|
5
|
+
|
|
6
|
+
AUTHORS:
|
|
7
|
+
|
|
8
|
+
- Ethan Van Andel (2009-2011): initial version and upgrades
|
|
9
|
+
|
|
10
|
+
- Robert Bradshaw (2009): his "complex_plot" was adapted for plot_colored
|
|
11
|
+
|
|
12
|
+
Development supported by NSF award No. 0702939.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
# ****************************************************************************
|
|
16
|
+
# Copyright (C) 2011 Ethan Van Andel <evlutte@gmail.com>,
|
|
17
|
+
#
|
|
18
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
19
|
+
#
|
|
20
|
+
# This code is distributed in the hope that it will be useful,
|
|
21
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
22
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
23
|
+
# General Public License for more details.
|
|
24
|
+
#
|
|
25
|
+
# The full text of the GPL is available at:
|
|
26
|
+
#
|
|
27
|
+
# https://www.gnu.org/licenses/
|
|
28
|
+
# ****************************************************************************
|
|
29
|
+
|
|
30
|
+
from cysignals.signals cimport sig_on, sig_off
|
|
31
|
+
|
|
32
|
+
from sage.misc.decorators import options
|
|
33
|
+
|
|
34
|
+
from sage.ext.fast_callable import fast_callable
|
|
35
|
+
|
|
36
|
+
from sage.rings.complex_double import CDF
|
|
37
|
+
|
|
38
|
+
from sage.arith.srange import srange
|
|
39
|
+
|
|
40
|
+
from sage.calculus.interpolation import spline
|
|
41
|
+
|
|
42
|
+
from sage.calculus.integration import numerical_integral
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
import numpy as np
|
|
46
|
+
cimport numpy as np
|
|
47
|
+
|
|
48
|
+
if int(np.version.short_version[0]) > 1:
|
|
49
|
+
np.set_printoptions(legacy="1.25")
|
|
50
|
+
|
|
51
|
+
from math import pi
|
|
52
|
+
from math import sin
|
|
53
|
+
from math import cos
|
|
54
|
+
|
|
55
|
+
from math import log # used for complex plot lightness
|
|
56
|
+
from math import atan
|
|
57
|
+
|
|
58
|
+
from cmath import exp
|
|
59
|
+
from cmath import phase
|
|
60
|
+
|
|
61
|
+
FLOAT = np.float64
|
|
62
|
+
ctypedef np.float64_t FLOAT_T
|
|
63
|
+
|
|
64
|
+
COMPLEX = np.complex128
|
|
65
|
+
ctypedef np.complex128_t COMPLEX_T
|
|
66
|
+
|
|
67
|
+
cdef FLOAT_T PI = pi
|
|
68
|
+
cdef FLOAT_T TWOPI = 2*PI
|
|
69
|
+
cdef COMPLEX_T I = complex(0, 1)
|
|
70
|
+
|
|
71
|
+
cdef class Riemann_Map:
|
|
72
|
+
r"""
|
|
73
|
+
The ``Riemann_Map`` class computes an interior or exterior Riemann map,
|
|
74
|
+
or an Ahlfors map of a region given by the supplied boundary curve(s)
|
|
75
|
+
and center point. The class also provides various methods to
|
|
76
|
+
evaluate, visualize, or extract data from the map.
|
|
77
|
+
|
|
78
|
+
A Riemann map conformally maps a simply connected region in
|
|
79
|
+
the complex plane to the unit disc. The Ahlfors map does the same thing
|
|
80
|
+
for multiply connected regions.
|
|
81
|
+
|
|
82
|
+
Note that all the methods are numerical. As a result all answers have
|
|
83
|
+
some imprecision. Moreover, maps computed with small number of
|
|
84
|
+
collocation points, or for unusually shaped regions, may be very
|
|
85
|
+
inaccurate. Error computations for the ellipse can be found in the
|
|
86
|
+
documentation for :meth:`analytic_boundary` and :meth:`analytic_interior`.
|
|
87
|
+
|
|
88
|
+
[BSV2010]_ provides an overview of the Riemann map and discusses the research
|
|
89
|
+
that lead to the creation of this module.
|
|
90
|
+
|
|
91
|
+
INPUT:
|
|
92
|
+
|
|
93
|
+
- ``fs`` -- list of the boundaries of the region, given as
|
|
94
|
+
complex-valued functions with domain `0` to `2*pi`. Note that the
|
|
95
|
+
outer boundary must be parameterized counter clockwise
|
|
96
|
+
(i.e. ``e^(I*t)``) while the inner boundaries must be clockwise
|
|
97
|
+
(i.e. ``e^(-I*t)``).
|
|
98
|
+
|
|
99
|
+
- ``fprimes`` -- list of the derivatives of the boundary functions
|
|
100
|
+
(Must be in the same order as ``fs``)
|
|
101
|
+
|
|
102
|
+
- ``a`` -- complex, the center of the Riemann map. Will be mapped to
|
|
103
|
+
the origin of the unit disc. Note that ``a`` MUST be within
|
|
104
|
+
the region in order for the results to be mathematically valid.
|
|
105
|
+
|
|
106
|
+
The following inputs may be passed in as named parameters:
|
|
107
|
+
|
|
108
|
+
- ``N`` -- integer (default: `500`); the number of collocation points
|
|
109
|
+
used to compute the map. More points will give more accurate results,
|
|
110
|
+
especially near the boundaries, but will take longer to compute.
|
|
111
|
+
|
|
112
|
+
- ``exterior`` -- boolean (default: ``False``); if set to ``True``, the
|
|
113
|
+
exterior map will be computed, mapping the exterior of the region to the
|
|
114
|
+
exterior of the unit circle.
|
|
115
|
+
|
|
116
|
+
The following inputs may be passed as named parameters in unusual
|
|
117
|
+
circumstances:
|
|
118
|
+
|
|
119
|
+
- ``ncorners`` -- integer (default: `4`); if mapping a figure with
|
|
120
|
+
(equally t-spaced) corners -- corners that make a significant change in
|
|
121
|
+
the direction of the boundary -- better results may be sometimes obtained by
|
|
122
|
+
accurately giving this parameter. Used to add the proper constant to
|
|
123
|
+
the theta correspondence function.
|
|
124
|
+
|
|
125
|
+
- ``opp`` -- boolean (default: ``False``); set to ``True`` in very rare
|
|
126
|
+
cases where the theta correspondence function is off by ``pi``, that
|
|
127
|
+
is, if red is mapped left of the origin in the color plot.
|
|
128
|
+
|
|
129
|
+
EXAMPLES:
|
|
130
|
+
|
|
131
|
+
The unit circle identity map::
|
|
132
|
+
|
|
133
|
+
sage: f(t) = e^(I*t)
|
|
134
|
+
sage: fprime(t) = I*e^(I*t)
|
|
135
|
+
sage: m = Riemann_Map([f], [fprime], 0) # long time (4 sec)
|
|
136
|
+
sage: m.plot_colored() + m.plot_spiderweb() # long time
|
|
137
|
+
Graphics object consisting of 22 graphics primitives
|
|
138
|
+
|
|
139
|
+
The exterior map for the unit circle::
|
|
140
|
+
|
|
141
|
+
sage: m = Riemann_Map([f], [fprime], 0, exterior=True) # long time (4 sec)
|
|
142
|
+
sage: #spiderwebs are not supported for exterior maps
|
|
143
|
+
sage: m.plot_colored() # long time
|
|
144
|
+
Graphics object consisting of 1 graphics primitive
|
|
145
|
+
|
|
146
|
+
The unit circle with a small hole::
|
|
147
|
+
|
|
148
|
+
sage: f(t) = e^(I*t)
|
|
149
|
+
sage: fprime(t) = I*e^(I*t)
|
|
150
|
+
sage: hf(t) = 0.5*e^(-I*t)
|
|
151
|
+
sage: hfprime(t) = 0.5*-I*e^(-I*t)
|
|
152
|
+
sage: m = Riemann_Map([f, hf], [fprime, hfprime], 0.5 + 0.5*I)
|
|
153
|
+
sage: #spiderweb and color plots cannot be added for multiply
|
|
154
|
+
sage: #connected regions. Instead we do this.
|
|
155
|
+
sage: m.plot_spiderweb(withcolor = True) # long time
|
|
156
|
+
Graphics object consisting of 3 graphics primitives
|
|
157
|
+
|
|
158
|
+
A square::
|
|
159
|
+
|
|
160
|
+
sage: ps = polygon_spline([(-1, -1), (1, -1), (1, 1), (-1, 1)])
|
|
161
|
+
sage: f = lambda t: ps.value(real(t))
|
|
162
|
+
sage: fprime = lambda t: ps.derivative(real(t))
|
|
163
|
+
sage: m = Riemann_Map([f], [fprime], 0.25, ncorners=4)
|
|
164
|
+
sage: m.plot_colored() + m.plot_spiderweb() # long time
|
|
165
|
+
Graphics object consisting of 22 graphics primitives
|
|
166
|
+
|
|
167
|
+
Compute rough error for this map::
|
|
168
|
+
|
|
169
|
+
sage: x = 0.75 # long time
|
|
170
|
+
sage: print("error = {}".format(m.inverse_riemann_map(m.riemann_map(x)) - x)) # long time
|
|
171
|
+
error = (-0.000...+0.0016...j)
|
|
172
|
+
|
|
173
|
+
A fun, complex region for demonstration purposes::
|
|
174
|
+
|
|
175
|
+
sage: f(t) = e^(I*t)
|
|
176
|
+
sage: fp(t) = I*e^(I*t)
|
|
177
|
+
sage: ef1(t) = .2*e^(-I*t) +.4+.4*I
|
|
178
|
+
sage: ef1p(t) = -I*.2*e^(-I*t)
|
|
179
|
+
sage: ef2(t) = .2*e^(-I*t) -.4+.4*I
|
|
180
|
+
sage: ef2p(t) = -I*.2*e^(-I*t)
|
|
181
|
+
sage: pts = [(-.5,-.15-20/1000),(-.6,-.27-10/1000),(-.45,-.45),(0,-.65+10/1000),(.45,-.45),(.6,-.27-10/1000),(.5,-.15-10/1000),(0,-.43+10/1000)]
|
|
182
|
+
sage: pts.reverse()
|
|
183
|
+
sage: cs = complex_cubic_spline(pts)
|
|
184
|
+
sage: mf = lambda x:cs.value(x)
|
|
185
|
+
sage: mfprime = lambda x: cs.derivative(x)
|
|
186
|
+
sage: m = Riemann_Map([f,ef1,ef2,mf],[fp,ef1p,ef2p,mfprime],0,N = 400) # long time
|
|
187
|
+
sage: p = m.plot_colored(plot_points = 400) # long time
|
|
188
|
+
|
|
189
|
+
ALGORITHM:
|
|
190
|
+
|
|
191
|
+
This class computes the Riemann Map via the Szego kernel using an
|
|
192
|
+
adaptation of the method described by [KT1986]_.
|
|
193
|
+
"""
|
|
194
|
+
cdef int N, B, ncorners
|
|
195
|
+
cdef f
|
|
196
|
+
cdef opp
|
|
197
|
+
cdef COMPLEX_T a
|
|
198
|
+
cdef np.ndarray tk, tk2
|
|
199
|
+
cdef np.ndarray cps, dps, szego, p_vector, pre_q_vector
|
|
200
|
+
cdef np.ndarray p_vector_inverse, sinalpha, cosalpha, theta_array
|
|
201
|
+
cdef x_range, y_range
|
|
202
|
+
cdef exterior
|
|
203
|
+
|
|
204
|
+
def __init__(self, fs, fprimes, COMPLEX_T a, int N=500, int ncorners=4,
|
|
205
|
+
opp=False, exterior=False):
|
|
206
|
+
"""
|
|
207
|
+
Initialize the ``Riemann_Map`` class. See the class :class:`Riemann_Map`
|
|
208
|
+
for full documentation on the input of this initialization method.
|
|
209
|
+
|
|
210
|
+
TESTS::
|
|
211
|
+
|
|
212
|
+
sage: f(t) = e^(I*t) - 0.5*e^(-I*t)
|
|
213
|
+
sage: fprime(t) = I*e^(I*t) + 0.5*I*e^(-I*t)
|
|
214
|
+
sage: m = Riemann_Map([f], [fprime], 0, N = 10)
|
|
215
|
+
"""
|
|
216
|
+
cdef double xmax, xmin, ymax, ymin, space
|
|
217
|
+
cdef int i, k
|
|
218
|
+
if N <= 2:
|
|
219
|
+
raise ValueError(
|
|
220
|
+
"The number of collocation points must be > 2.")
|
|
221
|
+
if exterior and a!=0:
|
|
222
|
+
raise ValueError("The exterior map requires a=0")
|
|
223
|
+
try:
|
|
224
|
+
fs = [fast_callable(f, domain=CDF) for f in fs]
|
|
225
|
+
fprimes = [fast_callable(f, domain=CDF) for f in fprimes]
|
|
226
|
+
except AttributeError:
|
|
227
|
+
pass
|
|
228
|
+
self.f = fs[0]
|
|
229
|
+
self.a = a
|
|
230
|
+
self.ncorners = ncorners
|
|
231
|
+
self.N = N # Number of collocation pts
|
|
232
|
+
self.opp = opp
|
|
233
|
+
self.exterior = exterior
|
|
234
|
+
self.tk = np.array(np.arange(N) * TWOPI / N + 0.001 / N,
|
|
235
|
+
dtype=FLOAT)
|
|
236
|
+
self.tk2 = np.zeros(N + 1, dtype=FLOAT)
|
|
237
|
+
for i in range(N):
|
|
238
|
+
self.tk2[i] = self.tk[i]
|
|
239
|
+
self.tk2[N] = TWOPI
|
|
240
|
+
self.B = len(fs) # number of boundaries of the figure
|
|
241
|
+
if self.exterior and (self.B > 1):
|
|
242
|
+
raise ValueError(
|
|
243
|
+
"The exterior map is undefined for multiply connected domains")
|
|
244
|
+
cdef np.ndarray[COMPLEX_T,ndim=2] cps = np.zeros([self.B, N],
|
|
245
|
+
dtype=COMPLEX)
|
|
246
|
+
cdef np.ndarray[COMPLEX_T,ndim=2] dps = np.zeros([self.B, N],
|
|
247
|
+
dtype=COMPLEX)
|
|
248
|
+
# Find the points on the boundaries and their derivatives.
|
|
249
|
+
if self.exterior:
|
|
250
|
+
for k in range(self.B):
|
|
251
|
+
for i in range(N):
|
|
252
|
+
fk = fs[k](self.tk[N-i-1])
|
|
253
|
+
cps[k, i] = complex(1/fk)
|
|
254
|
+
dps[k, i] = complex(1/fk**2*fprimes[k](self.tk[N-i-1]))
|
|
255
|
+
else:
|
|
256
|
+
for k in range(self.B):
|
|
257
|
+
for i in range(N):
|
|
258
|
+
cps[k, i] = complex(fs[k](self.tk[i]))
|
|
259
|
+
dps[k, i] = complex(fprimes[k](self.tk[i]))
|
|
260
|
+
if self.exterior:
|
|
261
|
+
xmax = (1/cps).real.max()
|
|
262
|
+
xmin = (1/cps).real.min()
|
|
263
|
+
ymax = (1/cps).imag.max()
|
|
264
|
+
ymin = (1/cps).imag.min()
|
|
265
|
+
else:
|
|
266
|
+
xmax = cps.real.max()
|
|
267
|
+
xmin = cps.real.min()
|
|
268
|
+
ymax = cps.imag.max()
|
|
269
|
+
ymin = cps.imag.min()
|
|
270
|
+
space = 0.1 * max(xmax - xmin, ymax - ymin)
|
|
271
|
+
# The default plotting window for this map.
|
|
272
|
+
self.cps = cps
|
|
273
|
+
self.dps = dps
|
|
274
|
+
self.x_range = (xmin - space, xmax + space)
|
|
275
|
+
self.y_range = (ymin - space, ymax + space)
|
|
276
|
+
# Now we do some more computation
|
|
277
|
+
self._generate_theta_array()
|
|
278
|
+
self._generate_interior_mapper()
|
|
279
|
+
self._generate_inverse_mapper()
|
|
280
|
+
|
|
281
|
+
def _repr_(self):
|
|
282
|
+
"""
|
|
283
|
+
Return a string representation of this :class:`Riemann_Map` object.
|
|
284
|
+
|
|
285
|
+
TESTS::
|
|
286
|
+
|
|
287
|
+
sage: f(t) = e^(I*t) - 0.5*e^(-I*t)
|
|
288
|
+
sage: fprime(t) = I*e^(I*t) + 0.5*I*e^(-I*t)
|
|
289
|
+
sage: isinstance(Riemann_Map([f], [fprime], 0, N = 10)._repr_(), str) # long time
|
|
290
|
+
True
|
|
291
|
+
"""
|
|
292
|
+
return "A Riemann or Ahlfors mapping of a figure to the unit circle."
|
|
293
|
+
|
|
294
|
+
cdef _generate_theta_array(self):
|
|
295
|
+
"""
|
|
296
|
+
Generates the essential data for the Riemann map, primarily the
|
|
297
|
+
Szegő kernel and boundary correspondence.
|
|
298
|
+
|
|
299
|
+
See [KT1986]_ for the algorithm.
|
|
300
|
+
|
|
301
|
+
TESTS::
|
|
302
|
+
|
|
303
|
+
sage: f(t) = e^(I*t) - 0.5*e^(-I*t)
|
|
304
|
+
sage: fprime(t) = I*e^(I*t) + 0.5*I*e^(-I*t)
|
|
305
|
+
sage: m = Riemann_Map([f], [fprime], 0, N = 10)
|
|
306
|
+
"""
|
|
307
|
+
cdef np.ndarray[COMPLEX_T, ndim=1] cp = self.cps.flatten()
|
|
308
|
+
cdef np.ndarray[COMPLEX_T, ndim=1] dp = self.dps.flatten()
|
|
309
|
+
cdef int N = self.N
|
|
310
|
+
cdef int NB = N * self.B
|
|
311
|
+
cdef int B = self.B
|
|
312
|
+
cdef int i, k
|
|
313
|
+
cdef FLOAT_T saa, t0
|
|
314
|
+
cdef np.ndarray[FLOAT_T, ndim=1] adp, sadp
|
|
315
|
+
cdef np.ndarray[COMPLEX_T, ndim=1] h, hconj, g, normalized_dp, C, phi
|
|
316
|
+
cdef np.ndarray[COMPLEX_T, ndim=2] K
|
|
317
|
+
cdef np.ndarray[FLOAT_T, ndim=2] theta_array
|
|
318
|
+
# Setting things up to use the Nystrom method
|
|
319
|
+
adp = abs(dp)
|
|
320
|
+
sadp = np.sqrt(adp)
|
|
321
|
+
h = 1 / (TWOPI * I) * ((dp / adp) / (self.a - cp))
|
|
322
|
+
hconj = h.conjugate()
|
|
323
|
+
g = -sadp * hconj
|
|
324
|
+
normalized_dp=dp/adp
|
|
325
|
+
C = I / N * sadp # equivalent to -TWOPI / N * 1 / (TWOPI * I) * sadp
|
|
326
|
+
errinvalid = np.geterr()['invalid'] # checks the current error handling for invalid
|
|
327
|
+
errdivide = np.geterr()['divide'] # checks the current error handling for divide
|
|
328
|
+
np.seterr(divide='ignore',invalid='ignore')
|
|
329
|
+
K = np.array([C * sadp[t] * (normalized_dp/(cp-cp[t]) -
|
|
330
|
+
(normalized_dp[t]/(cp-cp[t])).conjugate())
|
|
331
|
+
for t in np.arange(NB)], dtype=np.complex128)
|
|
332
|
+
np.seterr(divide=errdivide,invalid=errinvalid) # resets the error handling
|
|
333
|
+
for i in range(NB):
|
|
334
|
+
K[i, i] = 1
|
|
335
|
+
# Nystrom Method for solving 2nd kind integrals
|
|
336
|
+
phi = np.linalg.solve(K, g) / NB * TWOPI
|
|
337
|
+
# the all-important Szego kernel
|
|
338
|
+
szego = np.array(phi.flatten() / np.sqrt(dp), dtype=COMPLEX)
|
|
339
|
+
self.szego = szego.reshape([B, N])
|
|
340
|
+
# Finding the theta correspondence using phase. Misbehaves for some
|
|
341
|
+
# regions.
|
|
342
|
+
if B != 1:
|
|
343
|
+
theta_array = np.zeros([1, NB])
|
|
344
|
+
for i in range(NB):
|
|
345
|
+
theta_array[0, i] = phase(-I * np.power(phi[i], 2) * dp[i])
|
|
346
|
+
self.theta_array = np.concatenate(
|
|
347
|
+
[theta_array.reshape([B, N]), np.zeros([B, 1])], axis=1)
|
|
348
|
+
for k in range(B):
|
|
349
|
+
self.theta_array[k, N] = self.theta_array[k, 0] + TWOPI
|
|
350
|
+
# Finding the theta correspondence using abs. Well behaved, but
|
|
351
|
+
# doesn't work on multiply connected domains.
|
|
352
|
+
else:
|
|
353
|
+
phi2 = phi.reshape([self.B, N])
|
|
354
|
+
theta_array = np.zeros([B, N + 1], dtype=np.float64)
|
|
355
|
+
for k in range(B):
|
|
356
|
+
phik = phi2[k]
|
|
357
|
+
saa = (np.dot(abs(phi), abs(phi))) * TWOPI / NB
|
|
358
|
+
theta_array[k, 0] = 0
|
|
359
|
+
for i in range(1, N):
|
|
360
|
+
theta_array[k, i] = (
|
|
361
|
+
theta_array[k, i - 1] +
|
|
362
|
+
((TWOPI / NB * TWOPI *
|
|
363
|
+
abs(np.power(phi[1 * i], 2)) / saa +
|
|
364
|
+
TWOPI / NB * TWOPI *
|
|
365
|
+
abs(np.power(phi[1 * i - 1], 2)) / saa)) / 2)
|
|
366
|
+
tmax = int(0.5 * N / self.ncorners)
|
|
367
|
+
# Finding the initial value of the theta function.
|
|
368
|
+
phimax = -I * phik[tmax]**2 * self.dps[k, tmax]
|
|
369
|
+
if self.opp:
|
|
370
|
+
t0 = theta_array[k, tmax] + phase(phimax)
|
|
371
|
+
else:
|
|
372
|
+
t0 = theta_array[k, tmax] - phase(phimax)
|
|
373
|
+
for i in range(N):
|
|
374
|
+
theta_array[k, i] = theta_array[k, i] - t0
|
|
375
|
+
theta_array[k, N] = TWOPI + theta_array[k, 0]
|
|
376
|
+
self.theta_array = theta_array
|
|
377
|
+
|
|
378
|
+
def get_szego(self, int boundary=-1, absolute_value=False):
|
|
379
|
+
"""
|
|
380
|
+
Return a discretized version of the Szego kernel for each boundary
|
|
381
|
+
function.
|
|
382
|
+
|
|
383
|
+
INPUT:
|
|
384
|
+
|
|
385
|
+
The following inputs may be passed in as named parameters:
|
|
386
|
+
|
|
387
|
+
- ``boundary`` -- integer (default: `-1`); if < 0,
|
|
388
|
+
:meth:`get_theta_points` will return the points for all boundaries.
|
|
389
|
+
If >= 0, :meth:`get_theta_points` will return only the points for
|
|
390
|
+
the boundary specified.
|
|
391
|
+
|
|
392
|
+
- ``absolute_value`` -- boolean (default: ``False``); if ``True``, will
|
|
393
|
+
return the absolute value of the (complex valued) Szego kernel
|
|
394
|
+
instead of the kernel itself. Useful for plotting.
|
|
395
|
+
|
|
396
|
+
OUTPUT:
|
|
397
|
+
|
|
398
|
+
A list of points of the form
|
|
399
|
+
``[t value, value of the Szego kernel at that t]``.
|
|
400
|
+
|
|
401
|
+
EXAMPLES:
|
|
402
|
+
|
|
403
|
+
Generic use::
|
|
404
|
+
|
|
405
|
+
sage: f(t) = e^(I*t) - 0.5*e^(-I*t)
|
|
406
|
+
sage: fprime(t) = I*e^(I*t) + 0.5*I*e^(-I*t)
|
|
407
|
+
sage: m = Riemann_Map([f], [fprime], 0)
|
|
408
|
+
sage: sz = m.get_szego(boundary=0)
|
|
409
|
+
sage: points = m.get_szego(absolute_value=True)
|
|
410
|
+
sage: list_plot(points) # needs sage.plot
|
|
411
|
+
Graphics object consisting of 1 graphics primitive
|
|
412
|
+
|
|
413
|
+
Extending the points by a spline::
|
|
414
|
+
|
|
415
|
+
sage: s = spline(points)
|
|
416
|
+
sage: s(3*pi / 4)
|
|
417
|
+
0.0012158...
|
|
418
|
+
sage: plot(s,0,2*pi) # plot the kernel # needs sage.plot
|
|
419
|
+
Graphics object consisting of 1 graphics primitive
|
|
420
|
+
|
|
421
|
+
The unit circle with a small hole::
|
|
422
|
+
|
|
423
|
+
sage: f(t) = e^(I*t)
|
|
424
|
+
sage: fprime(t) = I*e^(I*t)
|
|
425
|
+
sage: hf(t) = 0.5*e^(-I*t)
|
|
426
|
+
sage: hfprime(t) = 0.5*-I*e^(-I*t)
|
|
427
|
+
sage: m = Riemann_Map([f, hf], [fprime, hfprime], 0.5 + 0.5*I)
|
|
428
|
+
|
|
429
|
+
Getting the szego for a specific boundary::
|
|
430
|
+
|
|
431
|
+
sage: sz0 = m.get_szego(boundary=0)
|
|
432
|
+
sage: sz1 = m.get_szego(boundary=1)
|
|
433
|
+
"""
|
|
434
|
+
if boundary < 0:
|
|
435
|
+
temptk = self.tk
|
|
436
|
+
for i in range(self.B - 1):
|
|
437
|
+
temptk = np.concatenate([temptk, self.tk])
|
|
438
|
+
if absolute_value:
|
|
439
|
+
return np.column_stack(
|
|
440
|
+
[temptk, abs(self.szego.flatten())]).tolist()
|
|
441
|
+
else:
|
|
442
|
+
return np.column_stack([temptk, self.szego.flatten()]).tolist()
|
|
443
|
+
else:
|
|
444
|
+
if absolute_value:
|
|
445
|
+
return np.column_stack(
|
|
446
|
+
[self.tk, abs(self.szego[boundary])]).tolist()
|
|
447
|
+
else:
|
|
448
|
+
return np.column_stack(
|
|
449
|
+
[self.tk, self.szego[boundary]]).tolist()
|
|
450
|
+
|
|
451
|
+
def get_theta_points(self, int boundary=-1):
|
|
452
|
+
"""
|
|
453
|
+
Return an array of points of the form
|
|
454
|
+
``[t value, theta in e^(I*theta)]``, that is, a discretized version
|
|
455
|
+
of the theta/boundary correspondence function. In other words, a point
|
|
456
|
+
in this array [t1, t2] represents that the boundary point given by f(t1)
|
|
457
|
+
is mapped to a point on the boundary of the unit circle given by e^(I*t2).
|
|
458
|
+
|
|
459
|
+
For multiply connected domains, ``get_theta_points`` will list the
|
|
460
|
+
points for each boundary in the order that they were supplied.
|
|
461
|
+
|
|
462
|
+
INPUT:
|
|
463
|
+
|
|
464
|
+
The following input must all be passed in as named parameters:
|
|
465
|
+
|
|
466
|
+
- ``boundary`` -- integer (default: `-1`); if < 0,
|
|
467
|
+
``get_theta_points()`` will return the points for all boundaries.
|
|
468
|
+
If >= 0, ``get_theta_points()`` will return only the points for
|
|
469
|
+
the boundary specified.
|
|
470
|
+
|
|
471
|
+
OUTPUT:
|
|
472
|
+
|
|
473
|
+
A list of points of the form ``[t value, theta in e^(I*theta)]``.
|
|
474
|
+
|
|
475
|
+
EXAMPLES:
|
|
476
|
+
|
|
477
|
+
Getting the list of points, extending it via a spline, getting the
|
|
478
|
+
points for only the outside of a multiply connected domain::
|
|
479
|
+
|
|
480
|
+
sage: f(t) = e^(I*t) - 0.5*e^(-I*t)
|
|
481
|
+
sage: fprime(t) = I*e^(I*t) + 0.5*I*e^(-I*t)
|
|
482
|
+
sage: m = Riemann_Map([f], [fprime], 0)
|
|
483
|
+
sage: points = m.get_theta_points()
|
|
484
|
+
sage: list_plot(points) # needs sage.plot
|
|
485
|
+
Graphics object consisting of 1 graphics primitive
|
|
486
|
+
|
|
487
|
+
Extending the points by a spline::
|
|
488
|
+
|
|
489
|
+
sage: s = spline(points)
|
|
490
|
+
sage: s(3*pi / 4)
|
|
491
|
+
1.627660...
|
|
492
|
+
|
|
493
|
+
The unit circle with a small hole::
|
|
494
|
+
|
|
495
|
+
sage: f(t) = e^(I*t)
|
|
496
|
+
sage: fprime(t) = I*e^(I*t)
|
|
497
|
+
sage: hf(t) = 0.5*e^(-I*t)
|
|
498
|
+
sage: hfprime(t) = 0.5*-I*e^(-I*t)
|
|
499
|
+
sage: m = Riemann_Map([f, hf], [hf, hfprime], 0.5 + 0.5*I)
|
|
500
|
+
|
|
501
|
+
Getting the boundary correspondence for a specific boundary::
|
|
502
|
+
|
|
503
|
+
sage: tp0 = m.get_theta_points(boundary=0)
|
|
504
|
+
sage: tp1 = m.get_theta_points(boundary=1)
|
|
505
|
+
"""
|
|
506
|
+
if boundary < 0:
|
|
507
|
+
temptk = self.tk2
|
|
508
|
+
for i in range(self.B - 1):
|
|
509
|
+
temptk = np.concatenate([temptk, self.tk2])
|
|
510
|
+
return np.column_stack(
|
|
511
|
+
[temptk, self.theta_array.flatten()]).tolist()
|
|
512
|
+
else:
|
|
513
|
+
return np.column_stack(
|
|
514
|
+
[self.tk2, self.theta_array[boundary]]).tolist()
|
|
515
|
+
|
|
516
|
+
cdef _generate_interior_mapper(self):
|
|
517
|
+
"""
|
|
518
|
+
Generates the data necessary to use the :meth:`riemann_map` function.
|
|
519
|
+
As much setup as possible is done here to minimize the computation
|
|
520
|
+
that must be done in ``riemann_map``.
|
|
521
|
+
|
|
522
|
+
TESTS::
|
|
523
|
+
|
|
524
|
+
sage: f(t) = e^(I*t) - 0.5*e^(-I*t)
|
|
525
|
+
sage: fprime(t) = I*e^(I*t) + 0.5*I*e^(-I*t)
|
|
526
|
+
sage: m = Riemann_Map([f], [fprime], 0, N = 10) # indirect doctest
|
|
527
|
+
"""
|
|
528
|
+
cdef int N = self.N
|
|
529
|
+
cdef double complex coeff = 3*I / (8*N)
|
|
530
|
+
dps = self.dps
|
|
531
|
+
theta_array = self.theta_array
|
|
532
|
+
cdef np.ndarray[double complex, ndim=2] p_vector = np.zeros(
|
|
533
|
+
[self.B, N + 1], dtype=np.complex128)
|
|
534
|
+
cdef int k, i
|
|
535
|
+
# Lots of setup for Simpson's method of integration.
|
|
536
|
+
for k in range(self.B):
|
|
537
|
+
for i in range(N // 3):
|
|
538
|
+
p_vector[k, 3*i] = (2*coeff * dps[k, 3*i] *
|
|
539
|
+
exp(I * theta_array[k, 3*i]))
|
|
540
|
+
p_vector[k, 3*i + 1] = (3*coeff * dps[k, 3*i + 1] *
|
|
541
|
+
exp(I * theta_array[k, 3*i + 1]))
|
|
542
|
+
p_vector[k, 3*i + 2] = (3*coeff * dps[k, 3*i + 2] *
|
|
543
|
+
exp(I * theta_array[k, 3*i + 2]))
|
|
544
|
+
p_vector[k, 0] = 1*coeff * dps[k, 0] * exp(I * theta_array[k, 0])
|
|
545
|
+
if N % 3 == 0:
|
|
546
|
+
p_vector[k, N] = 1*coeff * dps[k, 0] * exp(I*theta_array[k, 0])
|
|
547
|
+
elif (N - 2) % 3 == 0:
|
|
548
|
+
p_vector[k, N - 2] = ((coeff + I/(3*N)) * dps[k, N - 2] *
|
|
549
|
+
exp(I * theta_array[k, N - 2]))
|
|
550
|
+
p_vector[k, N - 1] = (4*I / (3*N) * dps[k, N - 1] *
|
|
551
|
+
exp(I * theta_array[k, N - 1]))
|
|
552
|
+
p_vector[k, N] = (I / (3*N) * dps[k, 0] *
|
|
553
|
+
exp(I * theta_array[k, 0]))
|
|
554
|
+
else:
|
|
555
|
+
p_vector[k, N - 4] = ((coeff + I / (3*N)) * dps[k, N - 4] *
|
|
556
|
+
exp(I * theta_array[k, N - 4]))
|
|
557
|
+
p_vector[k, N - 3] = (4*I / (3*N) * dps[k, N - 3] *
|
|
558
|
+
exp(I * theta_array[k, N - 3]))
|
|
559
|
+
p_vector[k, N - 2] = (2*I / (3*N) * dps[k, N - 2] *
|
|
560
|
+
exp(I * theta_array[k, N - 2]))
|
|
561
|
+
p_vector[k, N - 1] = (4*I / (3*N) * dps[k, N - 1] *
|
|
562
|
+
exp(I * theta_array[k, N - 1]))
|
|
563
|
+
p_vector[k, N] = (I / (3*N) * dps[k, 0] *
|
|
564
|
+
exp(I * theta_array[k, 0]))
|
|
565
|
+
self.p_vector = p_vector.flatten()
|
|
566
|
+
cdef np.ndarray[double complex, ndim=1] pq = self.cps[:,list(range(N))+[0]].flatten()
|
|
567
|
+
self.pre_q_vector = pq
|
|
568
|
+
|
|
569
|
+
cpdef riemann_map(self, COMPLEX_T pt):
|
|
570
|
+
"""
|
|
571
|
+
Return the Riemann mapping of a point.
|
|
572
|
+
|
|
573
|
+
That is, given ``pt`` on the interior of the mapped region,
|
|
574
|
+
``riemann_map`` will return the point on the unit disk that
|
|
575
|
+
``pt`` maps to. Note that this method only works for interior
|
|
576
|
+
points; accuracy breaks down very close to the boundary. To
|
|
577
|
+
get boundary correspondence, use :meth:`get_theta_points`.
|
|
578
|
+
|
|
579
|
+
INPUT:
|
|
580
|
+
|
|
581
|
+
- ``pt`` -- a complex number representing the point to be
|
|
582
|
+
inverse mapped
|
|
583
|
+
|
|
584
|
+
OUTPUT:
|
|
585
|
+
|
|
586
|
+
A complex number representing the point on the unit circle that
|
|
587
|
+
the input point maps to.
|
|
588
|
+
|
|
589
|
+
EXAMPLES:
|
|
590
|
+
|
|
591
|
+
Can work for different types of complex numbers::
|
|
592
|
+
|
|
593
|
+
sage: f(t) = e^(I*t) - 0.5*e^(-I*t)
|
|
594
|
+
sage: fprime(t) = I*e^(I*t) + 0.5*I*e^(-I*t)
|
|
595
|
+
sage: m = Riemann_Map([f], [fprime], 0)
|
|
596
|
+
sage: m.riemann_map(0.25 + sqrt(-0.5))
|
|
597
|
+
(0.137514...+0.876696...j)
|
|
598
|
+
sage: I = CDF.gen()
|
|
599
|
+
sage: m.riemann_map(1.3*I)
|
|
600
|
+
(-1.56...e-05+0.989694...j)
|
|
601
|
+
sage: m.riemann_map(0.4)
|
|
602
|
+
(0.73324...+3.2...e-06j)
|
|
603
|
+
sage: m.riemann_map(complex(-3, 0.0001))
|
|
604
|
+
(1.405757...e-05+8.06...e-10j)
|
|
605
|
+
"""
|
|
606
|
+
|
|
607
|
+
cdef COMPLEX_T pt1
|
|
608
|
+
cdef np.ndarray[COMPLEX_T, ndim=1] q_vector
|
|
609
|
+
if self.exterior:
|
|
610
|
+
pt1 = 1/pt
|
|
611
|
+
q_vector = 1 / (
|
|
612
|
+
self.pre_q_vector - pt1)
|
|
613
|
+
return -1/np.dot(self.p_vector, q_vector)
|
|
614
|
+
else:
|
|
615
|
+
pt1 = pt
|
|
616
|
+
q_vector = 1 / (
|
|
617
|
+
self.pre_q_vector - pt1)
|
|
618
|
+
return -np.dot(self.p_vector, q_vector)
|
|
619
|
+
|
|
620
|
+
cdef _generate_inverse_mapper(self):
|
|
621
|
+
"""
|
|
622
|
+
Generates the data necessary to use the
|
|
623
|
+
:meth:`inverse_riemann_map` function. As much setup as possible is
|
|
624
|
+
done here to minimize the computation that must be done in
|
|
625
|
+
``inverse_riemann_map``.
|
|
626
|
+
|
|
627
|
+
TESTS::
|
|
628
|
+
|
|
629
|
+
sage: f(t) = e^(I*t) - 0.5*e^(-I*t)
|
|
630
|
+
sage: fprime(t) = I*e^(I*t) + 0.5*I*e^(-I*t)
|
|
631
|
+
sage: m = Riemann_Map([f], [fprime], 0, N = 10) # indirect doctest
|
|
632
|
+
"""
|
|
633
|
+
cdef int N = self.N
|
|
634
|
+
cdef int B = self.B
|
|
635
|
+
cdef float di
|
|
636
|
+
theta_array = self.theta_array
|
|
637
|
+
self.p_vector_inverse = np.zeros([B, N], dtype=np.complex128)
|
|
638
|
+
# Setup for trapezoid integration because integration points are
|
|
639
|
+
# not equally spaced.
|
|
640
|
+
for k in range(B):
|
|
641
|
+
for i in range(N):
|
|
642
|
+
di = theta_array[k, (i + 1) % N] - theta_array[k, (i - 1) % N]
|
|
643
|
+
if di > PI:
|
|
644
|
+
di = di - TWOPI
|
|
645
|
+
elif di < -PI:
|
|
646
|
+
di = di + TWOPI
|
|
647
|
+
self.p_vector_inverse[k, i] = di / 2
|
|
648
|
+
self.sinalpha = np.zeros([B, N], dtype=np.float64)
|
|
649
|
+
for k in range(B):
|
|
650
|
+
for i in range(N):
|
|
651
|
+
self.sinalpha[k, i] = sin(-theta_array[k, i])
|
|
652
|
+
self.cosalpha = np.zeros([B, N], dtype=np.float64)
|
|
653
|
+
for k in range(B):
|
|
654
|
+
for i in range(N):
|
|
655
|
+
self.cosalpha[k, i] = cos(-theta_array[k, i])
|
|
656
|
+
|
|
657
|
+
cpdef inverse_riemann_map(self, COMPLEX_T pt):
|
|
658
|
+
"""
|
|
659
|
+
Return the inverse Riemann mapping of a point.
|
|
660
|
+
|
|
661
|
+
That is, given ``pt`` on the interior of the unit disc,
|
|
662
|
+
``inverse_riemann_map()`` will return the point on the
|
|
663
|
+
original region that would be Riemann mapped to ``pt``. Note
|
|
664
|
+
that this method does not work for multiply connected domains.
|
|
665
|
+
|
|
666
|
+
INPUT:
|
|
667
|
+
|
|
668
|
+
- ``pt`` -- a complex number (usually with absolute value <= 1)
|
|
669
|
+
representing the point to be inverse mapped
|
|
670
|
+
|
|
671
|
+
OUTPUT: the point on the region that Riemann maps to the input point
|
|
672
|
+
|
|
673
|
+
EXAMPLES:
|
|
674
|
+
|
|
675
|
+
Can work for different types of complex numbers::
|
|
676
|
+
|
|
677
|
+
sage: f(t) = e^(I*t) - 0.5*e^(-I*t)
|
|
678
|
+
sage: fprime(t) = I*e^(I*t) + 0.5*I*e^(-I*t)
|
|
679
|
+
sage: m = Riemann_Map([f], [fprime], 0)
|
|
680
|
+
sage: m.inverse_riemann_map(0.5 + sqrt(-0.5))
|
|
681
|
+
(0.406880...+0.3614702...j)
|
|
682
|
+
sage: m.inverse_riemann_map(0.95)
|
|
683
|
+
(0.486319...-4.90019052...j)
|
|
684
|
+
sage: m.inverse_riemann_map(0.25 - 0.3*I)
|
|
685
|
+
(0.1653244...-0.180936...j)
|
|
686
|
+
sage: m.inverse_riemann_map(complex(-0.2, 0.5))
|
|
687
|
+
(-0.156280...+0.321819...j)
|
|
688
|
+
"""
|
|
689
|
+
if self.exterior:
|
|
690
|
+
pt = 1/pt
|
|
691
|
+
r = abs(pt)
|
|
692
|
+
if r == 0:
|
|
693
|
+
stheta = 0
|
|
694
|
+
ctheta = 0
|
|
695
|
+
else:
|
|
696
|
+
stheta = pt.imag / r
|
|
697
|
+
ctheta = pt.real / r
|
|
698
|
+
k = 0
|
|
699
|
+
mapped = (1 - r**2) / TWOPI * np.dot(
|
|
700
|
+
self.p_vector_inverse[k] * self.cps[k],
|
|
701
|
+
1 / (1 + r**2 - 2*r *
|
|
702
|
+
(ctheta * self.cosalpha[k] - stheta * self.sinalpha[k])))
|
|
703
|
+
if self.exterior:
|
|
704
|
+
return 1/mapped
|
|
705
|
+
else:
|
|
706
|
+
return mapped
|
|
707
|
+
|
|
708
|
+
def plot_boundaries(self, plotjoined=True, rgbcolor=None, thickness=1):
|
|
709
|
+
"""
|
|
710
|
+
Plot the boundaries of the region for the Riemann map.
|
|
711
|
+
|
|
712
|
+
Note that this method DOES work for multiply connected domains.
|
|
713
|
+
|
|
714
|
+
INPUT:
|
|
715
|
+
|
|
716
|
+
The following inputs may be passed in as named parameters:
|
|
717
|
+
|
|
718
|
+
- ``plotjoined`` -- boolean (default: ``True``); if ``False``,
|
|
719
|
+
discrete points will be drawn; otherwise they will be connected
|
|
720
|
+
by lines. In this case, if ``plotjoined=False``, the points shown
|
|
721
|
+
will be the original collocation points used to generate the
|
|
722
|
+
Riemann map.
|
|
723
|
+
|
|
724
|
+
- ``rgbcolor`` -- float array (default: ``[0,0,0]``) the
|
|
725
|
+
red-green-blue color of the boundary
|
|
726
|
+
|
|
727
|
+
- ``thickness`` -- positive float (default: ``1``) the thickness of
|
|
728
|
+
the lines or points in the boundary
|
|
729
|
+
|
|
730
|
+
EXAMPLES:
|
|
731
|
+
|
|
732
|
+
General usage::
|
|
733
|
+
|
|
734
|
+
sage: f(t) = e^(I*t) - 0.5*e^(-I*t)
|
|
735
|
+
sage: fprime(t) = I*e^(I*t) + 0.5*I*e^(-I*t)
|
|
736
|
+
sage: m = Riemann_Map([f], [fprime], 0)
|
|
737
|
+
|
|
738
|
+
Default plot::
|
|
739
|
+
|
|
740
|
+
sage: m.plot_boundaries() # needs sage.plot
|
|
741
|
+
Graphics object consisting of 1 graphics primitive
|
|
742
|
+
|
|
743
|
+
Big blue collocation points::
|
|
744
|
+
|
|
745
|
+
sage: m.plot_boundaries(plotjoined=False, rgbcolor=[0,0,1], thickness=6) # needs sage.plot
|
|
746
|
+
Graphics object consisting of 1 graphics primitive
|
|
747
|
+
"""
|
|
748
|
+
from sage.plot.all import list_plot
|
|
749
|
+
|
|
750
|
+
if rgbcolor is None:
|
|
751
|
+
rgbcolor = [0, 0, 0]
|
|
752
|
+
|
|
753
|
+
plots = list(range(self.B))
|
|
754
|
+
for k in range(self.B):
|
|
755
|
+
# This conditional should be eliminated when the thickness/pointsize
|
|
756
|
+
# issue is resolved later. Same for the others in plot_spiderweb().
|
|
757
|
+
if plotjoined:
|
|
758
|
+
plots[k] = list_plot(
|
|
759
|
+
comp_pt(self.cps[k], 1), plotjoined=True,
|
|
760
|
+
rgbcolor=rgbcolor, thickness=thickness)
|
|
761
|
+
else:
|
|
762
|
+
plots[k] = list_plot(
|
|
763
|
+
comp_pt(self.cps[k], 1), rgbcolor=rgbcolor,
|
|
764
|
+
pointsize=thickness)
|
|
765
|
+
return sum(plots)
|
|
766
|
+
|
|
767
|
+
cpdef compute_on_grid(self, plot_range, int x_points):
|
|
768
|
+
"""
|
|
769
|
+
Compute the Riemann map on a grid of points.
|
|
770
|
+
|
|
771
|
+
Note that these points are complex of the form z = x + y*i.
|
|
772
|
+
|
|
773
|
+
INPUT:
|
|
774
|
+
|
|
775
|
+
- ``plot_range`` -- tuple of the form ``[xmin, xmax, ymin, ymax]``;
|
|
776
|
+
if the value is ``[]``, the default plotting window of the map will
|
|
777
|
+
be used
|
|
778
|
+
|
|
779
|
+
- ``x_points`` -- integer; the size of the grid in the x direction;
|
|
780
|
+
the number of points in the y direction is scaled accordingly
|
|
781
|
+
|
|
782
|
+
OUTPUT:
|
|
783
|
+
|
|
784
|
+
- a tuple containing ``[z_values, xmin, xmax, ymin, ymax]``
|
|
785
|
+
where ``z_values`` is the evaluation of the map on the specified grid.
|
|
786
|
+
|
|
787
|
+
EXAMPLES:
|
|
788
|
+
|
|
789
|
+
General usage::
|
|
790
|
+
|
|
791
|
+
sage: f(t) = e^(I*t) - 0.5*e^(-I*t)
|
|
792
|
+
sage: fprime(t) = I*e^(I*t) + 0.5*I*e^(-I*t)
|
|
793
|
+
sage: m = Riemann_Map([f], [fprime], 0)
|
|
794
|
+
sage: data = m.compute_on_grid([],5)
|
|
795
|
+
sage: data[0][8,1]
|
|
796
|
+
(-0.0879...+0.9709...j)
|
|
797
|
+
"""
|
|
798
|
+
cdef FLOAT_T xmin, xmax, xstep, ymin, ymax, ystep
|
|
799
|
+
cdef int y_points
|
|
800
|
+
if plot_range == []:
|
|
801
|
+
xmin = self.x_range[0]
|
|
802
|
+
xmax = self.x_range[1]
|
|
803
|
+
ymin = self.y_range[0]
|
|
804
|
+
ymax = self.y_range[1]
|
|
805
|
+
else:
|
|
806
|
+
xmin = plot_range[0]
|
|
807
|
+
xmax = plot_range[1]
|
|
808
|
+
ymin = plot_range[2]
|
|
809
|
+
ymax = plot_range[3]
|
|
810
|
+
xstep = (xmax - xmin) / x_points
|
|
811
|
+
ystep = xstep
|
|
812
|
+
y_points = int((ymax-ymin)/ ystep)
|
|
813
|
+
cdef Py_ssize_t i, j
|
|
814
|
+
cdef COMPLEX_T pt
|
|
815
|
+
cdef np.ndarray[COMPLEX_T] pre_q_vector = self.pre_q_vector
|
|
816
|
+
cdef np.ndarray[COMPLEX_T] p_vector = self.p_vector
|
|
817
|
+
cdef np.ndarray[COMPLEX_T, ndim=2] z_values = np.empty(
|
|
818
|
+
[y_points, x_points], dtype=np.complex128)
|
|
819
|
+
if self.exterior:
|
|
820
|
+
for i in range(x_points):
|
|
821
|
+
for j in range(y_points):
|
|
822
|
+
pt = 1/(xmin + 0.5*xstep + i*xstep + I*(ymin + 0.5*ystep + j*ystep))
|
|
823
|
+
z_values[j, i] = 1/(-np.dot(p_vector,1/(pre_q_vector - pt)))
|
|
824
|
+
else:
|
|
825
|
+
for i in range(x_points):
|
|
826
|
+
for j in range(y_points):
|
|
827
|
+
pt = xmin + 0.5*xstep + i*xstep + I*(ymin + 0.5*ystep + j*ystep)
|
|
828
|
+
z_values[j, i] = -np.dot(p_vector,1/(pre_q_vector - pt))
|
|
829
|
+
return z_values, xmin, xmax, ymin, ymax
|
|
830
|
+
|
|
831
|
+
@options(interpolation='catrom')
|
|
832
|
+
def plot_spiderweb(self, spokes=16, circles=4, pts=32, linescale=0.99,
|
|
833
|
+
rgbcolor=None, thickness=1,
|
|
834
|
+
plotjoined=True, withcolor=False,
|
|
835
|
+
plot_points=200, min_mag=0.001, **options):
|
|
836
|
+
"""
|
|
837
|
+
Generate a traditional "spiderweb plot" of the Riemann map.
|
|
838
|
+
|
|
839
|
+
This shows what concentric circles and radial lines map to.
|
|
840
|
+
The radial lines may exhibit erratic behavior near the
|
|
841
|
+
boundary; if this occurs, decreasing ``linescale`` may
|
|
842
|
+
mitigate the problem.
|
|
843
|
+
|
|
844
|
+
For multiply connected domains the spiderweb is by necessity
|
|
845
|
+
generated using the forward mapping. This method is more
|
|
846
|
+
computationally intensive. In addition, these spiderwebs cannot
|
|
847
|
+
be ``added`` to color plots. Instead the ``withcolor`` option
|
|
848
|
+
must be used.
|
|
849
|
+
|
|
850
|
+
In addition, spiderweb plots are not currently supported for
|
|
851
|
+
exterior maps.
|
|
852
|
+
|
|
853
|
+
INPUT:
|
|
854
|
+
|
|
855
|
+
The following inputs may be passed in as named parameters:
|
|
856
|
+
|
|
857
|
+
- ``spokes`` -- integer (default: 16); the number of equally
|
|
858
|
+
spaced radial lines to plot
|
|
859
|
+
|
|
860
|
+
- ``circles`` -- integer (default: 4); the number of equally
|
|
861
|
+
spaced circles about the center to plot
|
|
862
|
+
|
|
863
|
+
- ``pts`` -- integer (default: 32); the number of points to
|
|
864
|
+
plot. Each radial line is made by ``1*pts`` points, each circle
|
|
865
|
+
has ``2*pts`` points. Note that high values may cause erratic
|
|
866
|
+
behavior of the radial lines near the boundaries.
|
|
867
|
+
- only for simply connected domains
|
|
868
|
+
|
|
869
|
+
- ``linescale`` -- float between 0 and 1; shrinks the radial lines
|
|
870
|
+
away from the boundary to reduce erratic behavior
|
|
871
|
+
- only for simply connected domains
|
|
872
|
+
|
|
873
|
+
- ``rgbcolor`` -- float array (default: ``[0,0,0]``); the
|
|
874
|
+
red-green-blue color of the spiderweb
|
|
875
|
+
|
|
876
|
+
- ``thickness`` -- positive float (default: 1); the thickness of
|
|
877
|
+
the lines or points in the spiderweb
|
|
878
|
+
|
|
879
|
+
- ``plotjoined`` -- boolean (default: ``True``); if ``False``,
|
|
880
|
+
discrete points will be drawn; otherwise they will be connected
|
|
881
|
+
by lines
|
|
882
|
+
- only for simply connected domains
|
|
883
|
+
|
|
884
|
+
- ``withcolor`` -- boolean (default: ``False``); if ``True``,
|
|
885
|
+
the spiderweb will be overlaid on the basic color plot
|
|
886
|
+
|
|
887
|
+
- ``plot_points`` -- integer (default: 200); the size of the grid
|
|
888
|
+
in the x direction. The number of points in the y_direction is scaled
|
|
889
|
+
accordingly. Note that very large values can cause this function to
|
|
890
|
+
run slowly.
|
|
891
|
+
- only for multiply connected domains
|
|
892
|
+
|
|
893
|
+
- ``min_mag`` -- float (default: 0.001); the magnitude cutoff
|
|
894
|
+
below which spiderweb points are not drawn. This only applies
|
|
895
|
+
to multiply connected domains and is designed to prevent
|
|
896
|
+
"fuzz" at the edge of the domain. Some complicated multiply
|
|
897
|
+
connected domains (particularly those with corners) may
|
|
898
|
+
require a larger value to look clean outside.
|
|
899
|
+
|
|
900
|
+
EXAMPLES:
|
|
901
|
+
|
|
902
|
+
General usage::
|
|
903
|
+
|
|
904
|
+
sage: f(t) = e^(I*t) - 0.5*e^(-I*t)
|
|
905
|
+
sage: fprime(t) = I*e^(I*t) + 0.5*I*e^(-I*t)
|
|
906
|
+
sage: m = Riemann_Map([f], [fprime], 0)
|
|
907
|
+
|
|
908
|
+
Default plot::
|
|
909
|
+
|
|
910
|
+
sage: m.plot_spiderweb() # needs sage.plot
|
|
911
|
+
Graphics object consisting of 21 graphics primitives
|
|
912
|
+
|
|
913
|
+
Simplified plot with many discrete points::
|
|
914
|
+
|
|
915
|
+
sage: m.plot_spiderweb(spokes=4, circles=1, pts=400, # needs sage.plot
|
|
916
|
+
....: linescale=0.95, plotjoined=False)
|
|
917
|
+
Graphics object consisting of 6 graphics primitives
|
|
918
|
+
|
|
919
|
+
Plot with thick, red lines::
|
|
920
|
+
|
|
921
|
+
sage: m.plot_spiderweb(rgbcolor=[1,0,0], thickness=3) # needs sage.plot
|
|
922
|
+
Graphics object consisting of 21 graphics primitives
|
|
923
|
+
|
|
924
|
+
To generate the unit circle map, it's helpful to see what the
|
|
925
|
+
original spiderweb looks like::
|
|
926
|
+
|
|
927
|
+
sage: f(t) = e^(I*t)
|
|
928
|
+
sage: fprime(t) = I*e^(I*t)
|
|
929
|
+
sage: m = Riemann_Map([f], [fprime], 0, 1000)
|
|
930
|
+
sage: m.plot_spiderweb() # needs sage.plot
|
|
931
|
+
Graphics object consisting of 21 graphics primitives
|
|
932
|
+
|
|
933
|
+
A multiply connected region with corners. We set ``min_mag`` higher
|
|
934
|
+
to remove "fuzz" outside the domain::
|
|
935
|
+
|
|
936
|
+
sage: ps = polygon_spline([(-4,-2),(4,-2),(4,2),(-4,2)])
|
|
937
|
+
sage: z1 = lambda t: ps.value(t); z1p = lambda t: ps.derivative(t)
|
|
938
|
+
sage: z2(t) = -2+exp(-I*t); z2p(t) = -I*exp(-I*t)
|
|
939
|
+
sage: z3(t) = 2+exp(-I*t); z3p(t) = -I*exp(-I*t)
|
|
940
|
+
sage: m = Riemann_Map([z1,z2,z3], [z1p,z2p,z3p], 0, # long time
|
|
941
|
+
....: ncorners=4)
|
|
942
|
+
sage: p = m.plot_spiderweb(withcolor=True, plot_points=500, # long time, needs sage.plot
|
|
943
|
+
....: thickness=2.0, min_mag=0.1)
|
|
944
|
+
"""
|
|
945
|
+
from sage.plot.complex_plot import ComplexPlot
|
|
946
|
+
from sage.plot.all import list_plot, Graphics
|
|
947
|
+
|
|
948
|
+
cdef int k, i
|
|
949
|
+
if self.exterior:
|
|
950
|
+
raise ValueError(
|
|
951
|
+
"Spiderwebs for exterior maps are not currently supported")
|
|
952
|
+
|
|
953
|
+
if rgbcolor is None:
|
|
954
|
+
rgbcolor = [0, 0, 0]
|
|
955
|
+
|
|
956
|
+
if self.B == 1: # The efficient simply connected
|
|
957
|
+
edge = self.plot_boundaries(plotjoined=plotjoined,
|
|
958
|
+
rgbcolor=rgbcolor,
|
|
959
|
+
thickness=thickness)
|
|
960
|
+
circle_list = list(range(circles))
|
|
961
|
+
s = spline(np.column_stack([self.theta_array[0], self.tk2]).tolist())
|
|
962
|
+
tmax = self.theta_array[0, self.N]
|
|
963
|
+
tmin = self.theta_array[0, 0]
|
|
964
|
+
for k in range(circles):
|
|
965
|
+
temp = list(range(pts*2))
|
|
966
|
+
for i in range(2*pts):
|
|
967
|
+
temp[i] = self.inverse_riemann_map(
|
|
968
|
+
(k + 1) / (circles + 1.0) * exp(I*i * TWOPI / (2*pts)))
|
|
969
|
+
if plotjoined:
|
|
970
|
+
circle_list[k] = list_plot(comp_pt(temp, 1),
|
|
971
|
+
rgbcolor=rgbcolor,
|
|
972
|
+
thickness=thickness,
|
|
973
|
+
plotjoined=True)
|
|
974
|
+
else:
|
|
975
|
+
circle_list[k] = list_plot(comp_pt(temp, 1),
|
|
976
|
+
rgbcolor=rgbcolor,
|
|
977
|
+
pointsize=thickness)
|
|
978
|
+
line_list = list(range(spokes))
|
|
979
|
+
for k in range(spokes):
|
|
980
|
+
temp = list(range(pts))
|
|
981
|
+
angle = (k*1.0) / spokes * TWOPI
|
|
982
|
+
if angle >= tmax:
|
|
983
|
+
angle -= TWOPI
|
|
984
|
+
elif angle <= tmin:
|
|
985
|
+
angle += TWOPI
|
|
986
|
+
for i in range(pts - 1):
|
|
987
|
+
temp[i] = self.inverse_riemann_map(
|
|
988
|
+
(i * 1.0) / (pts * 1.0) * exp(I * angle) * linescale)
|
|
989
|
+
temp[pts - 1] = complex(
|
|
990
|
+
self.f(s(angle)) if angle <= tmax else self.f(s(angle-TWOPI)))
|
|
991
|
+
if plotjoined:
|
|
992
|
+
line_list[k] = list_plot(
|
|
993
|
+
comp_pt(temp, 0), rgbcolor=rgbcolor, thickness=thickness,
|
|
994
|
+
plotjoined=True)
|
|
995
|
+
else:
|
|
996
|
+
line_list[k] = list_plot(
|
|
997
|
+
comp_pt(temp, 0), rgbcolor=rgbcolor, pointsize=thickness)
|
|
998
|
+
if withcolor:
|
|
999
|
+
return edge + sum(circle_list) + sum(line_list) + \
|
|
1000
|
+
self.plot_colored(plot_points=plot_points)
|
|
1001
|
+
else:
|
|
1002
|
+
return edge + sum(circle_list) + sum(line_list)
|
|
1003
|
+
else: # The more difficult multiply connected
|
|
1004
|
+
z_values, xmin, xmax, ymin, ymax = self.compute_on_grid([],
|
|
1005
|
+
plot_points)
|
|
1006
|
+
xstep = (xmax-xmin)/plot_points
|
|
1007
|
+
ystep = (ymax-ymin)/plot_points
|
|
1008
|
+
dr, dtheta= get_derivatives(z_values, xstep, ystep) # clean later
|
|
1009
|
+
|
|
1010
|
+
g = Graphics()
|
|
1011
|
+
g.add_primitive(ComplexPlot(complex_to_spiderweb(z_values, dr,
|
|
1012
|
+
dtheta, spokes,
|
|
1013
|
+
circles,
|
|
1014
|
+
rgbcolor,
|
|
1015
|
+
thickness,
|
|
1016
|
+
withcolor,
|
|
1017
|
+
min_mag),
|
|
1018
|
+
(xmin, xmax), (ymin, ymax),options))
|
|
1019
|
+
return g + self.plot_boundaries(thickness = thickness)
|
|
1020
|
+
|
|
1021
|
+
@options(interpolation='catrom')
|
|
1022
|
+
def plot_colored(self, plot_range=None, int plot_points=100, **options):
|
|
1023
|
+
"""
|
|
1024
|
+
Generate a colored plot of the Riemann map.
|
|
1025
|
+
|
|
1026
|
+
A red point on the colored plot corresponds to a red point on
|
|
1027
|
+
the unit disc.
|
|
1028
|
+
|
|
1029
|
+
INPUT:
|
|
1030
|
+
|
|
1031
|
+
The following inputs may be passed in as named parameters:
|
|
1032
|
+
|
|
1033
|
+
- ``plot_range`` -- (default: ``[]``) list of 4 values
|
|
1034
|
+
``(xmin, xmax, ymin, ymax)``. Declare if you do not want the plot
|
|
1035
|
+
to use the default range for the figure.
|
|
1036
|
+
|
|
1037
|
+
- ``plot_points`` -- integer (default: 100); number of points to
|
|
1038
|
+
plot in the x direction. Points in the y direction are scaled
|
|
1039
|
+
accordingly. Note that very large values can cause this function to
|
|
1040
|
+
run slowly.
|
|
1041
|
+
|
|
1042
|
+
EXAMPLES:
|
|
1043
|
+
|
|
1044
|
+
Given a Riemann map m, general usage::
|
|
1045
|
+
|
|
1046
|
+
sage: f(t) = e^(I*t) - 0.5*e^(-I*t)
|
|
1047
|
+
sage: fprime(t) = I*e^(I*t) + 0.5*I*e^(-I*t)
|
|
1048
|
+
sage: m = Riemann_Map([f], [fprime], 0)
|
|
1049
|
+
sage: m.plot_colored() # needs sage.plot
|
|
1050
|
+
Graphics object consisting of 1 graphics primitive
|
|
1051
|
+
|
|
1052
|
+
Plot zoomed in on a specific spot::
|
|
1053
|
+
|
|
1054
|
+
sage: m.plot_colored(plot_range=[0,1,.25,.75]) # needs sage.plot
|
|
1055
|
+
Graphics object consisting of 1 graphics primitive
|
|
1056
|
+
|
|
1057
|
+
High resolution plot::
|
|
1058
|
+
|
|
1059
|
+
sage: m.plot_colored(plot_points=1000) # long time (29s on sage.math, 2012), needs sage.plot
|
|
1060
|
+
Graphics object consisting of 1 graphics primitive
|
|
1061
|
+
|
|
1062
|
+
To generate the unit circle map, it's helpful to see what the
|
|
1063
|
+
colors correspond to::
|
|
1064
|
+
|
|
1065
|
+
sage: f(t) = e^(I*t)
|
|
1066
|
+
sage: fprime(t) = I*e^(I*t)
|
|
1067
|
+
sage: m = Riemann_Map([f], [fprime], 0, 1000)
|
|
1068
|
+
sage: m.plot_colored() # needs sage.plot
|
|
1069
|
+
Graphics object consisting of 1 graphics primitive
|
|
1070
|
+
"""
|
|
1071
|
+
from sage.plot.complex_plot import ComplexPlot
|
|
1072
|
+
from sage.plot.all import Graphics
|
|
1073
|
+
|
|
1074
|
+
if plot_range is None:
|
|
1075
|
+
plot_range = []
|
|
1076
|
+
|
|
1077
|
+
z_values, xmin, xmax, ymin, ymax = self.compute_on_grid(plot_range,
|
|
1078
|
+
plot_points)
|
|
1079
|
+
g = Graphics()
|
|
1080
|
+
g.add_primitive(ComplexPlot(complex_to_rgb(z_values), (xmin, xmax),
|
|
1081
|
+
(ymin, ymax), options))
|
|
1082
|
+
return g
|
|
1083
|
+
|
|
1084
|
+
cdef comp_pt(clist, loop=True):
|
|
1085
|
+
"""
|
|
1086
|
+
Utility function to convert the list of complex numbers
|
|
1087
|
+
``xderivs = get_derivatives(z_values, xstep, ystep)[0]`` to the plottable
|
|
1088
|
+
`(x,y)` form. If ``loop=True``, then the first point will be
|
|
1089
|
+
added as the last, i.e. to plot a closed circle.
|
|
1090
|
+
|
|
1091
|
+
INPUT:
|
|
1092
|
+
|
|
1093
|
+
- ``clist`` -- list of complex numbers
|
|
1094
|
+
|
|
1095
|
+
- ``loop`` -- boolean (default: ``True``); controls whether or not the
|
|
1096
|
+
first point will be added as the last to plot a closed circle
|
|
1097
|
+
|
|
1098
|
+
EXAMPLES:
|
|
1099
|
+
|
|
1100
|
+
This tests it implicitly::
|
|
1101
|
+
|
|
1102
|
+
sage: f(t) = e^(I*t) - 0.5*e^(-I*t)
|
|
1103
|
+
sage: fprime(t) = I*e^(I*t) + 0.5*I*e^(-I*t)
|
|
1104
|
+
sage: m = Riemann_Map([f], [fprime], 0)
|
|
1105
|
+
sage: m.plot_spiderweb() # needs sage.plot
|
|
1106
|
+
Graphics object consisting of 21 graphics primitives
|
|
1107
|
+
"""
|
|
1108
|
+
list2 = [(c.real, c.imag) for c in clist]
|
|
1109
|
+
if loop:
|
|
1110
|
+
list2.append(list2[0])
|
|
1111
|
+
return list2
|
|
1112
|
+
|
|
1113
|
+
cpdef get_derivatives(np.ndarray[COMPLEX_T, ndim=2] z_values,
|
|
1114
|
+
FLOAT_T xstep, FLOAT_T ystep):
|
|
1115
|
+
"""
|
|
1116
|
+
Compute the r*e^(I*theta) form of derivatives from the grid of points. The
|
|
1117
|
+
derivatives are computed using quick-and-dirty taylor expansion and
|
|
1118
|
+
assuming analyticity. As such ``get_derivatives`` is primarily intended
|
|
1119
|
+
to be used for comparisons in ``plot_spiderweb`` and not for
|
|
1120
|
+
applications that require great precision.
|
|
1121
|
+
|
|
1122
|
+
INPUT:
|
|
1123
|
+
|
|
1124
|
+
- ``z_values`` -- the values for a complex function evaluated on a grid
|
|
1125
|
+
in the complex plane, usually from ``compute_on_grid``
|
|
1126
|
+
|
|
1127
|
+
- ``xstep`` -- float, the spacing of the grid points in the real direction
|
|
1128
|
+
|
|
1129
|
+
OUTPUT:
|
|
1130
|
+
|
|
1131
|
+
- A tuple of arrays, [``dr``, ``dtheta``], with each array 2 less in both
|
|
1132
|
+
dimensions than ``z_values``
|
|
1133
|
+
|
|
1134
|
+
- ``dr`` -- the abs of the derivative of the function in the +r direction
|
|
1135
|
+
- ``dtheta`` -- the rate of accumulation of angle in the +theta direction
|
|
1136
|
+
|
|
1137
|
+
EXAMPLES:
|
|
1138
|
+
|
|
1139
|
+
Standard usage with compute_on_grid::
|
|
1140
|
+
|
|
1141
|
+
sage: from sage.calculus.riemann import get_derivatives
|
|
1142
|
+
sage: f(t) = e^(I*t) - 0.5*e^(-I*t)
|
|
1143
|
+
sage: fprime(t) = I*e^(I*t) + 0.5*I*e^(-I*t)
|
|
1144
|
+
sage: m = Riemann_Map([f], [fprime], 0)
|
|
1145
|
+
sage: data = m.compute_on_grid([],19)
|
|
1146
|
+
sage: xstep = (data[2]-data[1])/19
|
|
1147
|
+
sage: ystep = (data[4]-data[3])/19
|
|
1148
|
+
sage: dr, dtheta = get_derivatives(data[0],xstep,ystep)
|
|
1149
|
+
sage: dr[8,8]
|
|
1150
|
+
0.241...
|
|
1151
|
+
sage: dtheta[5,5]
|
|
1152
|
+
5.907...
|
|
1153
|
+
"""
|
|
1154
|
+
cdef np.ndarray[COMPLEX_T, ndim=2] xderiv
|
|
1155
|
+
cdef np.ndarray[FLOAT_T, ndim = 2] dr, dtheta, zabs
|
|
1156
|
+
# (f(x+delta)-f(x-delta))/2delta
|
|
1157
|
+
xderiv = (z_values[1:-1,2:]-z_values[1:-1,:-2])/(2*xstep)
|
|
1158
|
+
# b/c the function is analytic, we know the magnitude of its
|
|
1159
|
+
# derivative is equal in all directions
|
|
1160
|
+
dr = np.abs(xderiv)
|
|
1161
|
+
# the abs(derivative) scaled by distance from origin
|
|
1162
|
+
zabs = np.abs(z_values[1:-1,1:-1])
|
|
1163
|
+
dtheta = np.divide(dr, zabs)
|
|
1164
|
+
return dr, dtheta
|
|
1165
|
+
|
|
1166
|
+
cpdef complex_to_spiderweb(np.ndarray[COMPLEX_T, ndim = 2] z_values,
|
|
1167
|
+
np.ndarray[FLOAT_T, ndim = 2] dr,
|
|
1168
|
+
np.ndarray[FLOAT_T, ndim = 2] dtheta,
|
|
1169
|
+
spokes, circles, rgbcolor, thickness,
|
|
1170
|
+
withcolor, min_mag):
|
|
1171
|
+
"""
|
|
1172
|
+
Convert a grid of complex numbers into a matrix containing rgb data
|
|
1173
|
+
for the Riemann spiderweb plot.
|
|
1174
|
+
|
|
1175
|
+
INPUT:
|
|
1176
|
+
|
|
1177
|
+
- ``z_values`` -- a grid of complex numbers, as a list of lists
|
|
1178
|
+
|
|
1179
|
+
- ``dr`` -- grid of floats, the r derivative of ``z_values``
|
|
1180
|
+
Used to determine precision
|
|
1181
|
+
|
|
1182
|
+
- ``dtheta`` -- grid of floats, the theta derivative of ``z_values``
|
|
1183
|
+
Used to determine precision
|
|
1184
|
+
|
|
1185
|
+
- ``spokes`` -- integer; the number of equally spaced radial lines to plot
|
|
1186
|
+
|
|
1187
|
+
- ``circles`` -- integer; the number of equally spaced circles about the
|
|
1188
|
+
center to plot
|
|
1189
|
+
|
|
1190
|
+
- ``rgbcolor`` -- float array; the red-green-blue color of the
|
|
1191
|
+
lines of the spiderweb
|
|
1192
|
+
|
|
1193
|
+
- ``thickness`` -- positive float; the thickness of the lines or points
|
|
1194
|
+
in the spiderweb
|
|
1195
|
+
|
|
1196
|
+
- ``withcolor`` -- boolean; if ``True`` the spiderweb will be overlaid
|
|
1197
|
+
on the basic color plot
|
|
1198
|
+
|
|
1199
|
+
- ``min_mag`` -- float; the magnitude cutoff below which spiderweb
|
|
1200
|
+
points are not drawn. This only applies to multiply connected
|
|
1201
|
+
domains and is designed to prevent "fuzz" at the edge of the
|
|
1202
|
+
domain. Some complicated multiply connected domains (particularly
|
|
1203
|
+
those with corners) may require a larger value to look clean
|
|
1204
|
+
outside.
|
|
1205
|
+
|
|
1206
|
+
OUTPUT:
|
|
1207
|
+
|
|
1208
|
+
An `N x M x 3` floating point Numpy array ``X``, where
|
|
1209
|
+
``X[i,j]`` is an (r,g,b) tuple.
|
|
1210
|
+
|
|
1211
|
+
EXAMPLES::
|
|
1212
|
+
|
|
1213
|
+
sage: from sage.calculus.riemann import complex_to_spiderweb
|
|
1214
|
+
sage: import numpy
|
|
1215
|
+
sage: zval = numpy.array([[0,1,1000], [.2+.3j,1,-.3j], [0,0,0]],
|
|
1216
|
+
....: dtype=numpy.complex128)
|
|
1217
|
+
sage: deriv = numpy.array([[.1]],dtype = numpy.float64)
|
|
1218
|
+
sage: complex_to_spiderweb(zval, deriv, deriv, 4, 4, [0,0,0], 1, False, 0.001)
|
|
1219
|
+
array([[[1., 1., 1.],
|
|
1220
|
+
[1., 1., 1.],
|
|
1221
|
+
[1., 1., 1.]],
|
|
1222
|
+
<BLANKLINE>
|
|
1223
|
+
[[1., 1., 1.],
|
|
1224
|
+
[0., 0., 0.],
|
|
1225
|
+
[1., 1., 1.]],
|
|
1226
|
+
<BLANKLINE>
|
|
1227
|
+
[[1., 1., 1.],
|
|
1228
|
+
[1., 1., 1.],
|
|
1229
|
+
[1., 1., 1.]]])
|
|
1230
|
+
|
|
1231
|
+
sage: complex_to_spiderweb(zval, deriv, deriv, 4, 4, [0,0,0], 1, True, 0.001)
|
|
1232
|
+
array([[[1. , 1. , 1. ],
|
|
1233
|
+
[1. , 0.05558355, 0.05558355],
|
|
1234
|
+
[0.17301243, 0. , 0. ]],
|
|
1235
|
+
<BLANKLINE>
|
|
1236
|
+
[[1. , 0.96804683, 0.48044583],
|
|
1237
|
+
[0. , 0. , 0. ],
|
|
1238
|
+
[0.77351965, 0.5470393 , 1. ]],
|
|
1239
|
+
<BLANKLINE>
|
|
1240
|
+
[[1. , 1. , 1. ],
|
|
1241
|
+
[1. , 1. , 1. ],
|
|
1242
|
+
[1. , 1. , 1. ]]])
|
|
1243
|
+
"""
|
|
1244
|
+
cdef Py_ssize_t i, j, imax, jmax
|
|
1245
|
+
cdef FLOAT_T mag, arg, target, precision, dmag, darg
|
|
1246
|
+
cdef COMPLEX_T z
|
|
1247
|
+
cdef FLOAT_T DMAX = 70 # change to adjust rate_of_change cutoff below
|
|
1248
|
+
precision = thickness/150.0
|
|
1249
|
+
imax = len(z_values)
|
|
1250
|
+
jmax = len(z_values[0])
|
|
1251
|
+
cdef np.ndarray[FLOAT_T, ndim=3, mode="c"] rgb
|
|
1252
|
+
if withcolor:
|
|
1253
|
+
rgb = complex_to_rgb(z_values)
|
|
1254
|
+
else:
|
|
1255
|
+
rgb = np.zeros(dtype=FLOAT, shape=(imax, jmax, 3))
|
|
1256
|
+
rgb += 1
|
|
1257
|
+
if circles != 0:
|
|
1258
|
+
circ_radii = srange(0, 1.0, 1.0/circles)
|
|
1259
|
+
else:
|
|
1260
|
+
circ_radii = []
|
|
1261
|
+
if spokes != 0:
|
|
1262
|
+
# both -pi and pi are included
|
|
1263
|
+
spoke_angles = srange(-PI,PI+TWOPI/spokes,TWOPI/spokes)
|
|
1264
|
+
else:
|
|
1265
|
+
spoke_angles = []
|
|
1266
|
+
for i in range(imax-2): # the d arrays are 1 smaller on each side
|
|
1267
|
+
for j in range(jmax-2):
|
|
1268
|
+
z = z_values[i+1,j+1]
|
|
1269
|
+
mag = abs(z)
|
|
1270
|
+
arg = phase(z)
|
|
1271
|
+
dmag = dr[i,j]
|
|
1272
|
+
darg = dtheta[i,j]
|
|
1273
|
+
# points that change too rapidly are presumed to be borders
|
|
1274
|
+
# points that are too small are presumed to be outside
|
|
1275
|
+
if darg < DMAX and mag > min_mag:
|
|
1276
|
+
for target in circ_radii:
|
|
1277
|
+
if abs(mag - target)/dmag < precision:
|
|
1278
|
+
rgb[i+1,j+1] = rgbcolor
|
|
1279
|
+
break
|
|
1280
|
+
for target in spoke_angles:
|
|
1281
|
+
if abs(arg - target)/darg < precision:
|
|
1282
|
+
rgb[i+1,j+1] = rgbcolor
|
|
1283
|
+
break
|
|
1284
|
+
return rgb
|
|
1285
|
+
|
|
1286
|
+
|
|
1287
|
+
cpdef complex_to_rgb(np.ndarray[COMPLEX_T, ndim=2] z_values):
|
|
1288
|
+
r"""
|
|
1289
|
+
Convert from a (Numpy) array of complex numbers to its corresponding
|
|
1290
|
+
matrix of RGB values. For internal use of :meth:`~Riemann_Map.plot_colored`
|
|
1291
|
+
only.
|
|
1292
|
+
|
|
1293
|
+
INPUT:
|
|
1294
|
+
|
|
1295
|
+
- ``z_values`` -- numpy array of complex numbers
|
|
1296
|
+
|
|
1297
|
+
OUTPUT:
|
|
1298
|
+
|
|
1299
|
+
An `N \times M \times 3` floating point Numpy array ``X``, where
|
|
1300
|
+
``X[i,j]`` is an (r,g,b) tuple.
|
|
1301
|
+
|
|
1302
|
+
EXAMPLES::
|
|
1303
|
+
|
|
1304
|
+
sage: from sage.calculus.riemann import complex_to_rgb
|
|
1305
|
+
sage: import numpy
|
|
1306
|
+
sage: complex_to_rgb(numpy.array([[0, 1, 1000]], dtype=numpy.complex128))
|
|
1307
|
+
array([[[1. , 1. , 1. ],
|
|
1308
|
+
[1. , 0.05558355, 0.05558355],
|
|
1309
|
+
[0.17301243, 0. , 0. ]]])
|
|
1310
|
+
|
|
1311
|
+
sage: complex_to_rgb(numpy.array([[0, 1j, 1000j]], dtype=numpy.complex128))
|
|
1312
|
+
array([[[1. , 1. , 1. ],
|
|
1313
|
+
[0.52779177, 1. , 0.05558355],
|
|
1314
|
+
[0.08650622, 0.17301243, 0. ]]])
|
|
1315
|
+
|
|
1316
|
+
|
|
1317
|
+
TESTS::
|
|
1318
|
+
|
|
1319
|
+
sage: complex_to_rgb([[0, 1, 10]])
|
|
1320
|
+
Traceback (most recent call last):
|
|
1321
|
+
...
|
|
1322
|
+
TypeError: Argument 'z_values' has incorrect type (expected numpy.ndarray, got list)
|
|
1323
|
+
"""
|
|
1324
|
+
cdef Py_ssize_t i, j, imax, jmax
|
|
1325
|
+
cdef FLOAT_T mag, arg
|
|
1326
|
+
cdef FLOAT_T lightness, hue, top, bot
|
|
1327
|
+
cdef FLOAT_T r, g, b
|
|
1328
|
+
cdef int ihue
|
|
1329
|
+
cdef COMPLEX_T z
|
|
1330
|
+
|
|
1331
|
+
imax = len(z_values)
|
|
1332
|
+
jmax = len(z_values[0])
|
|
1333
|
+
cdef np.ndarray[FLOAT_T, ndim=3, mode="c"] rgb = np.empty(
|
|
1334
|
+
dtype=FLOAT, shape=(imax, jmax, 3))
|
|
1335
|
+
|
|
1336
|
+
sig_on()
|
|
1337
|
+
for i in range(imax):
|
|
1338
|
+
row = z_values[i]
|
|
1339
|
+
for j in range(jmax):
|
|
1340
|
+
z = row[j]
|
|
1341
|
+
mag = abs(z)
|
|
1342
|
+
arg = phase(z)
|
|
1343
|
+
# tweak these levels to adjust how bright/dark the colors appear
|
|
1344
|
+
# output can range from -1 (black) to 1 (white)
|
|
1345
|
+
lightness = -(atan(log(mag*1.5+1)) * (4/PI) - 1)
|
|
1346
|
+
# in hsv, variable value, full saturation (s=1, v=1+lightness)
|
|
1347
|
+
if lightness < 0:
|
|
1348
|
+
bot = 0
|
|
1349
|
+
top = (1 + lightness)
|
|
1350
|
+
# in hsv, variable saturation, full value (v=1, s=1-lightness)
|
|
1351
|
+
else:
|
|
1352
|
+
bot = lightness
|
|
1353
|
+
top = 1
|
|
1354
|
+
# Note that does same thing as colorsys module hsv_to_rgb for
|
|
1355
|
+
# this setup, but in Cython.
|
|
1356
|
+
hue = 3*arg / PI
|
|
1357
|
+
# usual hsv hue is thus h=arg/(2*pi) for positive,
|
|
1358
|
+
# h=arg/(2*PI)+1 for negative
|
|
1359
|
+
if hue < 0:
|
|
1360
|
+
hue += 6
|
|
1361
|
+
ihue = <int>hue
|
|
1362
|
+
if ihue == 0:
|
|
1363
|
+
r = top
|
|
1364
|
+
g = bot + hue * (top - bot)
|
|
1365
|
+
b = bot
|
|
1366
|
+
elif ihue == 1:
|
|
1367
|
+
r = bot + (2 - hue) * (top - bot)
|
|
1368
|
+
g = top
|
|
1369
|
+
b = bot
|
|
1370
|
+
elif ihue == 2:
|
|
1371
|
+
r = bot
|
|
1372
|
+
g = top
|
|
1373
|
+
b = bot + (hue - 2) * (top - bot)
|
|
1374
|
+
elif ihue == 3:
|
|
1375
|
+
r = bot
|
|
1376
|
+
g = bot + (4 - hue) * (top - bot)
|
|
1377
|
+
b = top
|
|
1378
|
+
elif ihue == 4:
|
|
1379
|
+
r = bot + (hue - 4) * (top - bot)
|
|
1380
|
+
g = bot
|
|
1381
|
+
b = top
|
|
1382
|
+
else:
|
|
1383
|
+
r = top
|
|
1384
|
+
g = bot
|
|
1385
|
+
b = bot + (6 - hue) * (top - bot)
|
|
1386
|
+
rgb[i, j, 0] = r
|
|
1387
|
+
rgb[i, j, 1] = g
|
|
1388
|
+
rgb[i, j, 2] = b
|
|
1389
|
+
sig_off()
|
|
1390
|
+
return rgb
|
|
1391
|
+
|
|
1392
|
+
cpdef analytic_boundary(FLOAT_T t, int n, FLOAT_T epsilon):
|
|
1393
|
+
r"""
|
|
1394
|
+
Provides an exact (for `n = \infty`) Riemann boundary
|
|
1395
|
+
correspondence for the ellipse with axes `1 + \epsilon` and `1 - \epsilon`.
|
|
1396
|
+
The boundary is therefore given by `\exp(I t)+\epsilon\exp(-I t)`. It is
|
|
1397
|
+
primarily useful for testing the accuracy of the numerical
|
|
1398
|
+
:class:`Riemann_Map`.
|
|
1399
|
+
|
|
1400
|
+
INPUT:
|
|
1401
|
+
|
|
1402
|
+
- ``t`` -- the boundary parameter, from `0` to `2 \pi`
|
|
1403
|
+
|
|
1404
|
+
- ``n`` -- integer; the number of terms to include
|
|
1405
|
+
(10 is fairly accurate, 20 is very accurate)
|
|
1406
|
+
|
|
1407
|
+
- ``epsilon`` -- float; the skew of the ellipse (0 is circular)
|
|
1408
|
+
|
|
1409
|
+
OUTPUT:
|
|
1410
|
+
|
|
1411
|
+
A theta value from 0 to 2*pi, corresponding to the point on the
|
|
1412
|
+
circle e^(I*theta)
|
|
1413
|
+
|
|
1414
|
+
TESTS:
|
|
1415
|
+
|
|
1416
|
+
Checking the accuracy of this function for different n values::
|
|
1417
|
+
|
|
1418
|
+
sage: from sage.calculus.riemann import analytic_boundary
|
|
1419
|
+
sage: t100 = analytic_boundary(pi/2, 100, .3)
|
|
1420
|
+
sage: abs(analytic_boundary(pi/2, 10, .3) - t100) < 10^-8
|
|
1421
|
+
True
|
|
1422
|
+
sage: abs(analytic_boundary(pi/2, 20, .3) - t100) < 10^-15
|
|
1423
|
+
True
|
|
1424
|
+
|
|
1425
|
+
Using this to check the accuracy of the Riemann_Map boundary::
|
|
1426
|
+
|
|
1427
|
+
sage: f(t) = e^(I*t)+.3*e^(-I*t)
|
|
1428
|
+
sage: fp(t) = I*e^(I*t)-I*.3*e^(-I*t)
|
|
1429
|
+
sage: m = Riemann_Map([f], [fp],0,200)
|
|
1430
|
+
sage: s = spline(m.get_theta_points())
|
|
1431
|
+
sage: test_pt = uniform(0,2*pi)
|
|
1432
|
+
sage: s(test_pt) - analytic_boundary(test_pt,20, .3) < 10^-3
|
|
1433
|
+
True
|
|
1434
|
+
"""
|
|
1435
|
+
cdef FLOAT_T i
|
|
1436
|
+
cdef FLOAT_T result = t
|
|
1437
|
+
for i in range(1, n + 1):
|
|
1438
|
+
result += (2*(-1)**i/i)*(epsilon**i/(1+epsilon**(2*i)))*sin(2*i*t)
|
|
1439
|
+
return result
|
|
1440
|
+
|
|
1441
|
+
|
|
1442
|
+
cpdef cauchy_kernel(t, args):
|
|
1443
|
+
"""
|
|
1444
|
+
Intermediate function for the integration in :meth:`~Riemann_Map.analytic_interior`.
|
|
1445
|
+
|
|
1446
|
+
INPUT:
|
|
1447
|
+
|
|
1448
|
+
- ``t`` -- the boundary parameter, meant to be integrated over
|
|
1449
|
+
|
|
1450
|
+
- ``args`` -- tuple containing:
|
|
1451
|
+
|
|
1452
|
+
- ``epsilon`` -- float; the skew of the ellipse (0 is circular)
|
|
1453
|
+
|
|
1454
|
+
- ``z`` -- complex; the point to be mapped
|
|
1455
|
+
|
|
1456
|
+
- ``n`` -- integer; the number of terms to include
|
|
1457
|
+
(10 is fairly accurate, 20 is very accurate)
|
|
1458
|
+
|
|
1459
|
+
- ``part`` -- will return the real ('r'), imaginary ('i') or
|
|
1460
|
+
complex ('c') value of the kernel
|
|
1461
|
+
|
|
1462
|
+
TESTS:
|
|
1463
|
+
|
|
1464
|
+
This is primarily tested implicitly by :meth:`~Riemann_Map.analytic_interior`.
|
|
1465
|
+
Here is a simple test::
|
|
1466
|
+
|
|
1467
|
+
sage: from sage.calculus.riemann import cauchy_kernel
|
|
1468
|
+
sage: cauchy_kernel(.5,(.3, .1+.2*I, 10,'c'))
|
|
1469
|
+
(-0.584136405997...+0.5948650858950...j)
|
|
1470
|
+
"""
|
|
1471
|
+
cdef COMPLEX_T result
|
|
1472
|
+
cdef FLOAT_T epsilon = args[0]
|
|
1473
|
+
cdef COMPLEX_T z = args[1]
|
|
1474
|
+
cdef int n = args[2]
|
|
1475
|
+
part = args[3]
|
|
1476
|
+
result = exp(I*analytic_boundary(t,n, epsilon))/(exp(I*t)+epsilon*exp(-I*t)-z) * \
|
|
1477
|
+
(I*exp(I*t)-I*epsilon*exp(-I*t))
|
|
1478
|
+
if part == 'c':
|
|
1479
|
+
return result
|
|
1480
|
+
elif part == 'r':
|
|
1481
|
+
return result.real
|
|
1482
|
+
elif part == 'i':
|
|
1483
|
+
return result.imag
|
|
1484
|
+
else:
|
|
1485
|
+
return None
|
|
1486
|
+
|
|
1487
|
+
|
|
1488
|
+
cpdef analytic_interior(COMPLEX_T z, int n, FLOAT_T epsilon):
|
|
1489
|
+
"""
|
|
1490
|
+
Provides a nearly exact computation of the Riemann Map of an interior
|
|
1491
|
+
point of the ellipse with axes 1 + epsilon and 1 - epsilon. It is
|
|
1492
|
+
primarily useful for testing the accuracy of the numerical Riemann Map.
|
|
1493
|
+
|
|
1494
|
+
INPUT:
|
|
1495
|
+
|
|
1496
|
+
- ``z`` -- complex; the point to be mapped
|
|
1497
|
+
|
|
1498
|
+
- ``n`` -- integer; the number of terms to include
|
|
1499
|
+
(10 is fairly accurate, 20 is very accurate)
|
|
1500
|
+
|
|
1501
|
+
TESTS:
|
|
1502
|
+
|
|
1503
|
+
Testing the accuracy of :class:`Riemann_Map`::
|
|
1504
|
+
|
|
1505
|
+
sage: from sage.calculus.riemann import analytic_interior
|
|
1506
|
+
sage: f(t) = e^(I*t)+.3*e^(-I*t)
|
|
1507
|
+
sage: fp(t) = I*e^(I*t)-I*.3*e^(-I*t)
|
|
1508
|
+
sage: m = Riemann_Map([f],[fp],0,200)
|
|
1509
|
+
sage: abs(m.riemann_map(.5)-analytic_interior(.5, 20, .3)) < 10^-4
|
|
1510
|
+
True
|
|
1511
|
+
sage: m = Riemann_Map([f],[fp],0,2000)
|
|
1512
|
+
sage: abs(m.riemann_map(.5)-analytic_interior(.5, 20, .3)) < 10^-6
|
|
1513
|
+
True
|
|
1514
|
+
"""
|
|
1515
|
+
# evaluates the Cauchy integral of the boundary, split into the real
|
|
1516
|
+
# and imaginary results because numerical_integral can't handle complex data.
|
|
1517
|
+
rp = 1/(TWOPI)*numerical_integral(cauchy_kernel,0,2*pi,
|
|
1518
|
+
params = [epsilon,z,n,'i'])[0]
|
|
1519
|
+
ip = 1/(TWOPI*I)*numerical_integral(cauchy_kernel,0,2*pi,
|
|
1520
|
+
params = [epsilon,z,n,'r'])[0]
|
|
1521
|
+
return rp + ip
|