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,2546 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-modules
|
|
2
|
+
# sage.doctest: optional - numpy
|
|
3
|
+
r"""
|
|
4
|
+
Time Series
|
|
5
|
+
|
|
6
|
+
This is a module for working with discrete floating point time series.
|
|
7
|
+
It is designed so that every operation is very fast, typically much
|
|
8
|
+
faster than with other generic code, e.g., Python lists of doubles or
|
|
9
|
+
even NumPy arrays. The semantics of time series is more similar to
|
|
10
|
+
Python lists of doubles than Sage real double vectors or NumPy 1-D
|
|
11
|
+
arrays. In particular, time series are not endowed with much
|
|
12
|
+
algebraic structure and are always mutable.
|
|
13
|
+
|
|
14
|
+
.. NOTE::
|
|
15
|
+
|
|
16
|
+
NumPy arrays are faster at slicing, since slices return
|
|
17
|
+
references, and NumPy arrays have strides. However, this speed at
|
|
18
|
+
slicing makes NumPy slower at certain other operations.
|
|
19
|
+
|
|
20
|
+
EXAMPLES::
|
|
21
|
+
|
|
22
|
+
sage: set_random_seed(1)
|
|
23
|
+
sage: t = stats.TimeSeries([random()-0.5 for _ in range(10)]); t
|
|
24
|
+
[0.3294, 0.0959, -0.0706, -0.4646, 0.4311, 0.2275, -0.3840, -0.3528, -0.4119, -0.2933]
|
|
25
|
+
sage: t.sums()
|
|
26
|
+
[0.3294, 0.4253, 0.3547, -0.1099, 0.3212, 0.5487, 0.1647, -0.1882, -0.6001, -0.8933]
|
|
27
|
+
sage: t.exponential_moving_average(0.7)
|
|
28
|
+
[0.0000, 0.3294, 0.1660, 0.0003, -0.3251, 0.2042, 0.2205, -0.2027, -0.3078, -0.3807]
|
|
29
|
+
sage: t.standard_deviation()
|
|
30
|
+
0.33729638212891383
|
|
31
|
+
sage: t.mean()
|
|
32
|
+
-0.08933425506929439
|
|
33
|
+
sage: t.variance()
|
|
34
|
+
0.1137688493972542...
|
|
35
|
+
|
|
36
|
+
AUTHOR:
|
|
37
|
+
|
|
38
|
+
- William Stein
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
# ****************************************************************************
|
|
42
|
+
# Copyright (C) 2008 William Stein <wstein@gmail.com>
|
|
43
|
+
#
|
|
44
|
+
# This program is free software: you can redistribute it and/or modify
|
|
45
|
+
# it under the terms of the GNU General Public License as published by
|
|
46
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
47
|
+
# (at your option) any later version.
|
|
48
|
+
# https://www.gnu.org/licenses/
|
|
49
|
+
# ****************************************************************************
|
|
50
|
+
|
|
51
|
+
cimport cython
|
|
52
|
+
from cpython.bytes cimport PyBytes_FromStringAndSize, PyBytes_AsString
|
|
53
|
+
from libc.math cimport exp, log, pow, sqrt
|
|
54
|
+
from libc.string cimport memcpy
|
|
55
|
+
from cysignals.memory cimport sig_malloc, sig_free
|
|
56
|
+
from sage.structure.richcmp cimport rich_to_bool
|
|
57
|
+
|
|
58
|
+
cimport numpy as cnumpy
|
|
59
|
+
|
|
60
|
+
from sage.misc.randstate cimport randstate, current_randstate
|
|
61
|
+
from sage.misc.persist import register_unpickle_override
|
|
62
|
+
from sage.rings.integer import Integer
|
|
63
|
+
from sage.rings.real_double import RDF
|
|
64
|
+
from sage.modules.vector_real_double_dense cimport Vector_real_double_dense
|
|
65
|
+
|
|
66
|
+
max_print = 10
|
|
67
|
+
digits = 4
|
|
68
|
+
|
|
69
|
+
cdef class TimeSeries:
|
|
70
|
+
def __cinit__(self):
|
|
71
|
+
r"""
|
|
72
|
+
Create new empty uninitialized time series.
|
|
73
|
+
|
|
74
|
+
EXAMPLES:
|
|
75
|
+
|
|
76
|
+
This implicitly calls new::
|
|
77
|
+
|
|
78
|
+
sage: stats.TimeSeries([1,3,-4,5])
|
|
79
|
+
[1.0000, 3.0000, -4.0000, 5.0000]
|
|
80
|
+
"""
|
|
81
|
+
self._values = NULL
|
|
82
|
+
|
|
83
|
+
def __init__(self, values, bint initialize=True):
|
|
84
|
+
r"""
|
|
85
|
+
Initialize new time series.
|
|
86
|
+
|
|
87
|
+
INPUT:
|
|
88
|
+
|
|
89
|
+
- ``values`` -- integer (number of values) or an iterable of
|
|
90
|
+
floats
|
|
91
|
+
|
|
92
|
+
- ``initialize`` -- boolean (default: ``True``); if ``False``, do not
|
|
93
|
+
bother to zero out the entries of the new time series.
|
|
94
|
+
For large series that you are going to just fill in,
|
|
95
|
+
this can be way faster.
|
|
96
|
+
|
|
97
|
+
EXAMPLES:
|
|
98
|
+
|
|
99
|
+
This implicitly calls init::
|
|
100
|
+
|
|
101
|
+
sage: stats.TimeSeries([pi, 3, 18.2]) # needs sage.symbolic
|
|
102
|
+
[3.1416, 3.0000, 18.2000]
|
|
103
|
+
|
|
104
|
+
Conversion from a NumPy 1-D array, which is very fast::
|
|
105
|
+
|
|
106
|
+
sage: v = stats.TimeSeries([1..5])
|
|
107
|
+
sage: w = v.numpy()
|
|
108
|
+
sage: stats.TimeSeries(w)
|
|
109
|
+
[1.0000, 2.0000, 3.0000, 4.0000, 5.0000]
|
|
110
|
+
|
|
111
|
+
Conversion from an n-dimensional NumPy array also works::
|
|
112
|
+
|
|
113
|
+
sage: import numpy
|
|
114
|
+
sage: v = numpy.array([[1,2], [3,4]], dtype=float); v
|
|
115
|
+
array([[1., 2.],
|
|
116
|
+
[3., 4.]])
|
|
117
|
+
sage: stats.TimeSeries(v)
|
|
118
|
+
[1.0000, 2.0000, 3.0000, 4.0000]
|
|
119
|
+
sage: stats.TimeSeries(v[:,0])
|
|
120
|
+
[1.0000, 3.0000]
|
|
121
|
+
sage: u = numpy.array([[1,2],[3,4]])
|
|
122
|
+
sage: stats.TimeSeries(u)
|
|
123
|
+
[1.0000, 2.0000, 3.0000, 4.0000]
|
|
124
|
+
|
|
125
|
+
For speed purposes we don't initialize (so value is garbage)::
|
|
126
|
+
|
|
127
|
+
sage: t = stats.TimeSeries(10, initialize=False)
|
|
128
|
+
"""
|
|
129
|
+
cdef Vector_real_double_dense z
|
|
130
|
+
cdef cnumpy.ndarray np
|
|
131
|
+
cdef double *np_data
|
|
132
|
+
cdef unsigned int j
|
|
133
|
+
if isinstance(values, (int, Integer)):
|
|
134
|
+
self._length = values
|
|
135
|
+
values = None
|
|
136
|
+
elif isinstance(values, (Vector_real_double_dense, cnumpy.ndarray)):
|
|
137
|
+
if isinstance(values, Vector_real_double_dense):
|
|
138
|
+
np = values._vector_numpy
|
|
139
|
+
else:
|
|
140
|
+
np = values
|
|
141
|
+
|
|
142
|
+
if np.ndim != 1:
|
|
143
|
+
np = np.reshape([np.size])
|
|
144
|
+
|
|
145
|
+
# Make the array be the correct type and have a C array
|
|
146
|
+
# for a data structure. If the array already is the
|
|
147
|
+
# correct type and has a C array, nothing is done, so this
|
|
148
|
+
# should be fast in the common case.
|
|
149
|
+
np = np.astype('double')
|
|
150
|
+
np = cnumpy.PyArray_GETCONTIGUOUS(np)
|
|
151
|
+
np_data = <double*> cnumpy.PyArray_DATA(np)
|
|
152
|
+
self._length = np.shape[0]
|
|
153
|
+
self._values = <double*> sig_malloc(sizeof(double) * self._length)
|
|
154
|
+
if self._values == NULL:
|
|
155
|
+
raise MemoryError
|
|
156
|
+
|
|
157
|
+
memcpy(self._values, np_data, sizeof(double)*self._length)
|
|
158
|
+
return
|
|
159
|
+
else:
|
|
160
|
+
values = [float(x) for x in values]
|
|
161
|
+
self._length = len(values)
|
|
162
|
+
|
|
163
|
+
self._values = <double*> sig_malloc(sizeof(double) * self._length)
|
|
164
|
+
if self._values == NULL:
|
|
165
|
+
raise MemoryError
|
|
166
|
+
if not initialize: return
|
|
167
|
+
cdef Py_ssize_t i
|
|
168
|
+
if values is not None:
|
|
169
|
+
for i from 0 <= i < self._length:
|
|
170
|
+
self._values[i] = values[i]
|
|
171
|
+
else:
|
|
172
|
+
for i from 0 <= i < self._length:
|
|
173
|
+
self._values[i] = 0
|
|
174
|
+
|
|
175
|
+
def __reduce__(self):
|
|
176
|
+
r"""
|
|
177
|
+
Used in pickling time series.
|
|
178
|
+
|
|
179
|
+
EXAMPLES::
|
|
180
|
+
|
|
181
|
+
sage: v = stats.TimeSeries([1,-3.5])
|
|
182
|
+
sage: v.__reduce__()
|
|
183
|
+
(<cyfunction unpickle_time_series_v1 at ...>, (..., 2))
|
|
184
|
+
sage: loads(dumps(v)) == v
|
|
185
|
+
True
|
|
186
|
+
|
|
187
|
+
Note that dumping and loading with compress ``False`` is much faster,
|
|
188
|
+
though dumping with compress ``True`` can save a lot of space::
|
|
189
|
+
|
|
190
|
+
sage: v = stats.TimeSeries([1..10^5])
|
|
191
|
+
sage: loads(dumps(v, compress=False),compress=False) == v
|
|
192
|
+
True
|
|
193
|
+
"""
|
|
194
|
+
buf = PyBytes_FromStringAndSize(<char*>self._values, self._length*sizeof(double)/sizeof(char))
|
|
195
|
+
return unpickle_time_series_v1, (buf, self._length)
|
|
196
|
+
|
|
197
|
+
def __richcmp__(TimeSeries self, other, int op):
|
|
198
|
+
r"""
|
|
199
|
+
Compare ``self`` and ``other``. This has the same semantics
|
|
200
|
+
as list comparison.
|
|
201
|
+
|
|
202
|
+
EXAMPLES::
|
|
203
|
+
|
|
204
|
+
sage: v = stats.TimeSeries([1,2,3]); w = stats.TimeSeries([1,2])
|
|
205
|
+
sage: v < w
|
|
206
|
+
False
|
|
207
|
+
sage: w < v
|
|
208
|
+
True
|
|
209
|
+
sage: v == v
|
|
210
|
+
True
|
|
211
|
+
sage: w == w
|
|
212
|
+
True
|
|
213
|
+
"""
|
|
214
|
+
cdef Py_ssize_t i
|
|
215
|
+
cdef double d
|
|
216
|
+
if not isinstance(other, TimeSeries):
|
|
217
|
+
return NotImplemented
|
|
218
|
+
_other = <TimeSeries>other
|
|
219
|
+
for i in range(min(self._length, _other._length)):
|
|
220
|
+
d = self._values[i] - _other._values[i]
|
|
221
|
+
if d:
|
|
222
|
+
return rich_to_bool(op, -1 if d < 0 else 1)
|
|
223
|
+
c = self._length - _other._length
|
|
224
|
+
if c:
|
|
225
|
+
return rich_to_bool(op, -1 if c < 0 else 1)
|
|
226
|
+
return rich_to_bool(op, 0)
|
|
227
|
+
|
|
228
|
+
def __dealloc__(self):
|
|
229
|
+
r"""
|
|
230
|
+
Free up memory used by a time series.
|
|
231
|
+
|
|
232
|
+
EXAMPLES:
|
|
233
|
+
|
|
234
|
+
This tests ``__dealloc__`` implicitly::
|
|
235
|
+
|
|
236
|
+
sage: v = stats.TimeSeries([1,3,-4,5])
|
|
237
|
+
sage: del v
|
|
238
|
+
"""
|
|
239
|
+
sig_free(self._values)
|
|
240
|
+
|
|
241
|
+
def vector(self):
|
|
242
|
+
r"""
|
|
243
|
+
Return real double vector whose entries are the values of this
|
|
244
|
+
time series. This is useful since vectors have standard
|
|
245
|
+
algebraic structure and play well with matrices.
|
|
246
|
+
|
|
247
|
+
OUTPUT: a real double vector
|
|
248
|
+
|
|
249
|
+
EXAMPLES::
|
|
250
|
+
|
|
251
|
+
sage: v = stats.TimeSeries([1..10])
|
|
252
|
+
sage: v.vector()
|
|
253
|
+
(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0)
|
|
254
|
+
"""
|
|
255
|
+
V = RDF**self._length
|
|
256
|
+
# A copy of the numpy array is made in the vector constructor
|
|
257
|
+
cdef Vector_real_double_dense x = Vector_real_double_dense(V, self.numpy(copy=False))
|
|
258
|
+
return x
|
|
259
|
+
|
|
260
|
+
def __repr__(self):
|
|
261
|
+
r"""
|
|
262
|
+
Return string representation of ``self``.
|
|
263
|
+
|
|
264
|
+
EXAMPLES::
|
|
265
|
+
|
|
266
|
+
sage: v = stats.TimeSeries([1,3.1908439,-4,5.93932])
|
|
267
|
+
sage: v.__repr__()
|
|
268
|
+
'[1.0000, 3.1908, -4.0000, 5.9393]'
|
|
269
|
+
|
|
270
|
+
By default 4 digits after the decimal point are displayed. To
|
|
271
|
+
change this, change ``sage.stats.time_series.digits``. ::
|
|
272
|
+
|
|
273
|
+
sage: sage.stats.time_series.digits = 2
|
|
274
|
+
sage: v.__repr__()
|
|
275
|
+
'[1.00, 3.19, -4.00, 5.94]'
|
|
276
|
+
sage: v
|
|
277
|
+
[1.00, 3.19, -4.00, 5.94]
|
|
278
|
+
sage: sage.stats.time_series.digits = 4
|
|
279
|
+
sage: v
|
|
280
|
+
[1.0000, 3.1908, -4.0000, 5.9393]
|
|
281
|
+
"""
|
|
282
|
+
return self._repr()
|
|
283
|
+
|
|
284
|
+
def _repr(self, prec=None):
|
|
285
|
+
r"""
|
|
286
|
+
Print representation of a time series.
|
|
287
|
+
|
|
288
|
+
INPUT:
|
|
289
|
+
|
|
290
|
+
- ``prec`` -- (default: ``None``) number of digits of precision or
|
|
291
|
+
``None``. If ``None`` use the default
|
|
292
|
+
``sage.stats.time_series.digits``.
|
|
293
|
+
|
|
294
|
+
OUTPUT: string
|
|
295
|
+
|
|
296
|
+
EXAMPLES::
|
|
297
|
+
|
|
298
|
+
sage: v = stats.TimeSeries([1,3.1908439,-4,5.93932])
|
|
299
|
+
sage: v._repr()
|
|
300
|
+
'[1.0000, 3.1908, -4.0000, 5.9393]'
|
|
301
|
+
sage: v._repr(10)
|
|
302
|
+
'[1.0000000000, 3.1908439000, -4.0000000000, 5.9393200000]'
|
|
303
|
+
sage: v._repr(2)
|
|
304
|
+
'[1.00, 3.19, -4.00, 5.94]'
|
|
305
|
+
"""
|
|
306
|
+
if prec is None: prec = digits
|
|
307
|
+
format = '%.' + str(prec) + 'f'
|
|
308
|
+
if len(self) > max_print:
|
|
309
|
+
v0 = self[:max_print//2]
|
|
310
|
+
v1 = self[-max_print//2:]
|
|
311
|
+
return '[' + ', '.join(format % x for x in v0) + ' ... ' + \
|
|
312
|
+
', '.join(format % x for x in v1) + ']'
|
|
313
|
+
else:
|
|
314
|
+
return '[' + ', '.join(format % x for x in self) + ']'
|
|
315
|
+
|
|
316
|
+
def __len__(self):
|
|
317
|
+
r"""
|
|
318
|
+
Return the number of entries in this time series.
|
|
319
|
+
|
|
320
|
+
OUTPUT: Python integer
|
|
321
|
+
|
|
322
|
+
EXAMPLES::
|
|
323
|
+
|
|
324
|
+
sage: v = stats.TimeSeries([1,3.1908439,-4,5.93932])
|
|
325
|
+
sage: v.__len__()
|
|
326
|
+
4
|
|
327
|
+
sage: len(v)
|
|
328
|
+
4
|
|
329
|
+
"""
|
|
330
|
+
return self._length
|
|
331
|
+
|
|
332
|
+
def __getitem__(self, i):
|
|
333
|
+
r"""
|
|
334
|
+
Return `i`-th entry or slice of ``self``.
|
|
335
|
+
|
|
336
|
+
EXAMPLES::
|
|
337
|
+
|
|
338
|
+
sage: v = stats.TimeSeries([1,-4,3,-2.5,-4,3])
|
|
339
|
+
sage: v[2]
|
|
340
|
+
3.0
|
|
341
|
+
sage: v[-1]
|
|
342
|
+
3.0
|
|
343
|
+
sage: v[-10]
|
|
344
|
+
Traceback (most recent call last):
|
|
345
|
+
...
|
|
346
|
+
IndexError: TimeSeries index out of range
|
|
347
|
+
sage: v[5]
|
|
348
|
+
3.0
|
|
349
|
+
sage: v[6]
|
|
350
|
+
Traceback (most recent call last):
|
|
351
|
+
...
|
|
352
|
+
IndexError: TimeSeries index out of range
|
|
353
|
+
|
|
354
|
+
Some slice examples::
|
|
355
|
+
|
|
356
|
+
sage: v[-3:]
|
|
357
|
+
[-2.5000, -4.0000, 3.0000]
|
|
358
|
+
sage: v[-3:-1]
|
|
359
|
+
[-2.5000, -4.0000]
|
|
360
|
+
sage: v[::2]
|
|
361
|
+
[1.0000, 3.0000, -4.0000]
|
|
362
|
+
sage: v[3:20]
|
|
363
|
+
[-2.5000, -4.0000, 3.0000]
|
|
364
|
+
sage: v[3:2]
|
|
365
|
+
[]
|
|
366
|
+
|
|
367
|
+
Make a copy::
|
|
368
|
+
|
|
369
|
+
sage: v[:]
|
|
370
|
+
[1.0000, -4.0000, 3.0000, -2.5000, -4.0000, 3.0000]
|
|
371
|
+
|
|
372
|
+
Reverse the time series::
|
|
373
|
+
|
|
374
|
+
sage: v[::-1]
|
|
375
|
+
[3.0000, -4.0000, -2.5000, 3.0000, -4.0000, 1.0000]
|
|
376
|
+
"""
|
|
377
|
+
cdef Py_ssize_t start, stop, step, j
|
|
378
|
+
cdef TimeSeries t
|
|
379
|
+
if isinstance(i, slice):
|
|
380
|
+
start = 0 if (i.start is None) else i.start
|
|
381
|
+
stop = self._length if (i.stop is None) else i.stop
|
|
382
|
+
step = 1 if (i.step is None) else i.step
|
|
383
|
+
if start < 0:
|
|
384
|
+
start += self._length
|
|
385
|
+
if start < 0: start = 0
|
|
386
|
+
elif start >= self._length:
|
|
387
|
+
start = self._length - 1
|
|
388
|
+
if stop < 0:
|
|
389
|
+
stop += self._length
|
|
390
|
+
if stop < 0: stop = 0
|
|
391
|
+
elif stop > self._length:
|
|
392
|
+
stop = self._length
|
|
393
|
+
if start >= stop:
|
|
394
|
+
return new_time_series(0)
|
|
395
|
+
if step < 0:
|
|
396
|
+
step = -step
|
|
397
|
+
t = new_time_series((stop-start)/step)
|
|
398
|
+
for j from 0 <= j < (stop-start)/step:
|
|
399
|
+
t._values[j] = self._values[stop-1 - j*step]
|
|
400
|
+
elif step > 1:
|
|
401
|
+
t = new_time_series((stop-start)/step)
|
|
402
|
+
for j from 0 <= j < (stop-start)/step:
|
|
403
|
+
t._values[j] = self._values[j*step+start]
|
|
404
|
+
else:
|
|
405
|
+
t = new_time_series(stop-start)
|
|
406
|
+
memcpy(t._values, self._values + start, sizeof(double)*t._length)
|
|
407
|
+
return t
|
|
408
|
+
else:
|
|
409
|
+
j = i
|
|
410
|
+
if j < 0:
|
|
411
|
+
j += self._length
|
|
412
|
+
if j < 0:
|
|
413
|
+
raise IndexError("TimeSeries index out of range")
|
|
414
|
+
elif j >= self._length:
|
|
415
|
+
raise IndexError("TimeSeries index out of range")
|
|
416
|
+
return self._values[j]
|
|
417
|
+
|
|
418
|
+
def __setitem__(self, Py_ssize_t i, double x):
|
|
419
|
+
r"""
|
|
420
|
+
Set the `i`-th entry of ``self`` to ``x``.
|
|
421
|
+
|
|
422
|
+
INPUT:
|
|
423
|
+
|
|
424
|
+
- ``i`` -- nonnegative integer
|
|
425
|
+
|
|
426
|
+
- ``x`` -- a float
|
|
427
|
+
|
|
428
|
+
EXAMPLES::
|
|
429
|
+
|
|
430
|
+
sage: v = stats.TimeSeries([1,3,-4,5.93932]); v
|
|
431
|
+
[1.0000, 3.0000, -4.0000, 5.9393]
|
|
432
|
+
sage: v[0] = -5.5; v
|
|
433
|
+
[-5.5000, 3.0000, -4.0000, 5.9393]
|
|
434
|
+
sage: v[-1] = 3.2; v
|
|
435
|
+
[-5.5000, 3.0000, -4.0000, 3.2000]
|
|
436
|
+
sage: v[10]
|
|
437
|
+
Traceback (most recent call last):
|
|
438
|
+
...
|
|
439
|
+
IndexError: TimeSeries index out of range
|
|
440
|
+
sage: v[-5]
|
|
441
|
+
Traceback (most recent call last):
|
|
442
|
+
...
|
|
443
|
+
IndexError: TimeSeries index out of range
|
|
444
|
+
"""
|
|
445
|
+
if i < 0:
|
|
446
|
+
i += self._length
|
|
447
|
+
if i < 0:
|
|
448
|
+
raise IndexError("TimeSeries index out of range")
|
|
449
|
+
elif i >= self._length:
|
|
450
|
+
raise IndexError("TimeSeries index out of range")
|
|
451
|
+
self._values[i] = x
|
|
452
|
+
|
|
453
|
+
def __copy__(self):
|
|
454
|
+
r"""
|
|
455
|
+
Return a copy of ``self``.
|
|
456
|
+
|
|
457
|
+
EXAMPLES::
|
|
458
|
+
|
|
459
|
+
sage: v = stats.TimeSeries([1,-4,3,-2.5,-4,3])
|
|
460
|
+
sage: v.__copy__()
|
|
461
|
+
[1.0000, -4.0000, 3.0000, -2.5000, -4.0000, 3.0000]
|
|
462
|
+
sage: copy(v)
|
|
463
|
+
[1.0000, -4.0000, 3.0000, -2.5000, -4.0000, 3.0000]
|
|
464
|
+
sage: copy(v) is v
|
|
465
|
+
False
|
|
466
|
+
"""
|
|
467
|
+
cdef Py_ssize_t i
|
|
468
|
+
cdef TimeSeries t = new_time_series(self._length)
|
|
469
|
+
memcpy(t._values, self._values, sizeof(double)*self._length)
|
|
470
|
+
return t
|
|
471
|
+
|
|
472
|
+
def __add__(left, right):
|
|
473
|
+
r"""
|
|
474
|
+
Concatenate the time series ``self`` and ``right``.
|
|
475
|
+
|
|
476
|
+
.. NOTE::
|
|
477
|
+
|
|
478
|
+
To add a single number to the entries of a time series,
|
|
479
|
+
use the ``add_scalar`` method, and to add componentwise use
|
|
480
|
+
the ``add_entries`` method.
|
|
481
|
+
|
|
482
|
+
INPUT:
|
|
483
|
+
|
|
484
|
+
- ``right`` -- a time series
|
|
485
|
+
|
|
486
|
+
OUTPUT: a time series
|
|
487
|
+
|
|
488
|
+
EXAMPLES::
|
|
489
|
+
|
|
490
|
+
sage: v = stats.TimeSeries([1,2,3]); w = stats.TimeSeries([1,2])
|
|
491
|
+
sage: v + w
|
|
492
|
+
[1.0000, 2.0000, 3.0000, 1.0000, 2.0000]
|
|
493
|
+
sage: v = stats.TimeSeries([1,2,-5]); v
|
|
494
|
+
[1.0000, 2.0000, -5.0000]
|
|
495
|
+
|
|
496
|
+
Note that both summands must be a time series::
|
|
497
|
+
|
|
498
|
+
sage: v + list(range(4))
|
|
499
|
+
Traceback (most recent call last):
|
|
500
|
+
...
|
|
501
|
+
TypeError: right operand must be a time series
|
|
502
|
+
sage: [1,5] + v
|
|
503
|
+
Traceback (most recent call last):
|
|
504
|
+
...
|
|
505
|
+
TypeError: left operand must be a time series
|
|
506
|
+
"""
|
|
507
|
+
if not isinstance(right, TimeSeries):
|
|
508
|
+
raise TypeError("right operand must be a time series")
|
|
509
|
+
if not isinstance(left, TimeSeries):
|
|
510
|
+
raise TypeError("left operand must be a time series")
|
|
511
|
+
cdef TimeSeries R = right
|
|
512
|
+
cdef TimeSeries L = left
|
|
513
|
+
cdef TimeSeries t = new_time_series(L._length + R._length)
|
|
514
|
+
memcpy(t._values, L._values, sizeof(double)*L._length)
|
|
515
|
+
memcpy(t._values + L._length, R._values, sizeof(double)*R._length)
|
|
516
|
+
return t
|
|
517
|
+
|
|
518
|
+
def __mul__(left, right):
|
|
519
|
+
r"""
|
|
520
|
+
Multiply a time series by an integer n, which (like for lists)
|
|
521
|
+
results in the time series concatenated with itself n times.
|
|
522
|
+
|
|
523
|
+
.. NOTE::
|
|
524
|
+
|
|
525
|
+
To multiply all the entries of a time series by a single
|
|
526
|
+
scalar, use the ``scale`` method.
|
|
527
|
+
|
|
528
|
+
INPUT:
|
|
529
|
+
|
|
530
|
+
- ``left``, ``right`` -- integer and a time series
|
|
531
|
+
|
|
532
|
+
OUTPUT: a time series
|
|
533
|
+
|
|
534
|
+
EXAMPLES::
|
|
535
|
+
|
|
536
|
+
sage: v = stats.TimeSeries([1,2,-5]); v
|
|
537
|
+
[1.0000, 2.0000, -5.0000]
|
|
538
|
+
sage: v*3
|
|
539
|
+
[1.0000, 2.0000, -5.0000, 1.0000, 2.0000, -5.0000, 1.0000, 2.0000, -5.0000]
|
|
540
|
+
sage: 3*v
|
|
541
|
+
[1.0000, 2.0000, -5.0000, 1.0000, 2.0000, -5.0000, 1.0000, 2.0000, -5.0000]
|
|
542
|
+
sage: v*v
|
|
543
|
+
Traceback (most recent call last):
|
|
544
|
+
...
|
|
545
|
+
TypeError: 'sage.stats.time_series.TimeSeries' object cannot be interpreted as an integer
|
|
546
|
+
"""
|
|
547
|
+
cdef Py_ssize_t n, i
|
|
548
|
+
cdef TimeSeries T
|
|
549
|
+
if isinstance(left, TimeSeries):
|
|
550
|
+
T = left
|
|
551
|
+
n = right
|
|
552
|
+
else:
|
|
553
|
+
T = right
|
|
554
|
+
n = left
|
|
555
|
+
# Make n copies of T concatenated together
|
|
556
|
+
cdef TimeSeries v = new_time_series(T._length * n)
|
|
557
|
+
for i from 0 <= i < n:
|
|
558
|
+
memcpy(v._values + i*T._length, T._values, sizeof(double)*T._length)
|
|
559
|
+
return v
|
|
560
|
+
|
|
561
|
+
def autoregressive_fit(self, M):
|
|
562
|
+
r"""
|
|
563
|
+
This method fits the time series to an autoregressive process
|
|
564
|
+
of order ``M``. That is, we assume the process is given by
|
|
565
|
+
`X_t-\mu=a_1(X_{t-1}-\mu)+a_2(X_{t-1}-\mu)+\cdots+a_M(X_{t-M}-\mu)+Z_t`
|
|
566
|
+
where `\mu` is the mean of the process and `Z_t` is noise.
|
|
567
|
+
This method returns estimates for `a_1,\dots,a_M`.
|
|
568
|
+
|
|
569
|
+
The method works by solving the Yule-Walker equations
|
|
570
|
+
`\Gamma a =\gamma`, where `\gamma=(\gamma(1),\dots,\gamma(M))`,
|
|
571
|
+
`a=(a_1,\dots,a_M)` with `\gamma(i)` the autocovariance of lag `i`
|
|
572
|
+
and `\Gamma_{ij}=\gamma(i-j)`.
|
|
573
|
+
|
|
574
|
+
|
|
575
|
+
.. WARNING::
|
|
576
|
+
|
|
577
|
+
The input sequence is assumed to be stationary, which
|
|
578
|
+
means that the autocovariance `\langle y_j y_k \rangle` depends
|
|
579
|
+
only on the difference `|j-k|`.
|
|
580
|
+
|
|
581
|
+
INPUT:
|
|
582
|
+
|
|
583
|
+
- ``M`` -- integer
|
|
584
|
+
|
|
585
|
+
OUTPUT: a time series -- the coefficients of the autoregressive process
|
|
586
|
+
|
|
587
|
+
EXAMPLES::
|
|
588
|
+
|
|
589
|
+
sage: set_random_seed(0)
|
|
590
|
+
sage: v = stats.TimeSeries(10^4).randomize('normal').sums()
|
|
591
|
+
sage: F = v.autoregressive_fit(100)
|
|
592
|
+
sage: v
|
|
593
|
+
[0.6767, 0.2756, 0.6332, 0.0469, -0.8897 ... 87.6759, 87.6825, 87.4120, 87.6639, 86.3194]
|
|
594
|
+
sage: v.autoregressive_forecast(F)
|
|
595
|
+
86.0177285042...
|
|
596
|
+
sage: F
|
|
597
|
+
[1.0148, -0.0029, -0.0105, 0.0067, -0.0232 ... -0.0106, -0.0068, 0.0085, -0.0131, 0.0092]
|
|
598
|
+
|
|
599
|
+
sage: set_random_seed(0)
|
|
600
|
+
sage: t = stats.TimeSeries(2000)
|
|
601
|
+
sage: z = stats.TimeSeries(2000)
|
|
602
|
+
sage: z.randomize('normal',1)
|
|
603
|
+
[1.6767, 0.5989, 1.3576, 0.4136, 0.0635 ... 1.0057, -1.1467, 1.2809, 1.5705, 1.1095]
|
|
604
|
+
sage: t[0]=1
|
|
605
|
+
sage: t[1]=2
|
|
606
|
+
sage: for i in range(2,2000):
|
|
607
|
+
....: t[i]=t[i-1]-0.5*t[i-2]+z[i]
|
|
608
|
+
sage: c=t[0:-1].autoregressive_fit(2) #recovers recurrence relation
|
|
609
|
+
sage: c #should be close to [1,-0.5]
|
|
610
|
+
[1.0371, -0.5199]
|
|
611
|
+
"""
|
|
612
|
+
acvs = [self.autocovariance(i) for i in range(M+1)]
|
|
613
|
+
return autoregressive_fit(acvs)
|
|
614
|
+
|
|
615
|
+
def autoregressive_forecast(self, filter):
|
|
616
|
+
r"""
|
|
617
|
+
Given the autoregression coefficients as outputted by the
|
|
618
|
+
:meth:`autoregressive_fit` command, compute the forecast for the next
|
|
619
|
+
term in the series.
|
|
620
|
+
|
|
621
|
+
INPUT:
|
|
622
|
+
|
|
623
|
+
- ``filter`` -- a time series outputted by the ``autoregressive_fit``
|
|
624
|
+
command
|
|
625
|
+
|
|
626
|
+
EXAMPLES::
|
|
627
|
+
|
|
628
|
+
sage: set_random_seed(0)
|
|
629
|
+
sage: v = stats.TimeSeries(100).randomize('normal').sums()
|
|
630
|
+
sage: F = v[:-1].autoregressive_fit(5); F
|
|
631
|
+
[1.0019, -0.0524, -0.0643, 0.1323, -0.0539]
|
|
632
|
+
sage: v.autoregressive_forecast(F)
|
|
633
|
+
11.7820298611...
|
|
634
|
+
sage: v
|
|
635
|
+
[0.6767, 0.2756, 0.6332, 0.0469, -0.8897 ... 9.2447, 9.6709, 10.4037, 10.4836, 12.1960]
|
|
636
|
+
"""
|
|
637
|
+
cdef TimeSeries filt
|
|
638
|
+
if isinstance(filter, TimeSeries):
|
|
639
|
+
filt = filter
|
|
640
|
+
else:
|
|
641
|
+
filt = TimeSeries(filter)
|
|
642
|
+
|
|
643
|
+
cdef double f = 0
|
|
644
|
+
cdef Py_ssize_t i
|
|
645
|
+
for i from 0 <= i < min(self._length, filt._length):
|
|
646
|
+
f += self._values[self._length - i - 1] * filt._values[i]
|
|
647
|
+
return f
|
|
648
|
+
|
|
649
|
+
def reversed(self):
|
|
650
|
+
r"""
|
|
651
|
+
Return new time series obtain from this time series by
|
|
652
|
+
reversing the order of the entries in this time series.
|
|
653
|
+
|
|
654
|
+
OUTPUT: a time series
|
|
655
|
+
|
|
656
|
+
EXAMPLES::
|
|
657
|
+
|
|
658
|
+
sage: v = stats.TimeSeries([1..5])
|
|
659
|
+
sage: v.reversed()
|
|
660
|
+
[5.0000, 4.0000, 3.0000, 2.0000, 1.0000]
|
|
661
|
+
"""
|
|
662
|
+
cdef Py_ssize_t i, n = self._length-1
|
|
663
|
+
cdef TimeSeries t = new_time_series(self._length)
|
|
664
|
+
|
|
665
|
+
for i from 0 <= i < self._length:
|
|
666
|
+
t._values[i] = self._values[n - i]
|
|
667
|
+
return t
|
|
668
|
+
|
|
669
|
+
def extend(self, right):
|
|
670
|
+
r"""
|
|
671
|
+
Extend this time series by appending elements from the iterable
|
|
672
|
+
``right``.
|
|
673
|
+
|
|
674
|
+
INPUT:
|
|
675
|
+
|
|
676
|
+
- ``right`` -- iterable that can be converted to a time series
|
|
677
|
+
|
|
678
|
+
EXAMPLES::
|
|
679
|
+
|
|
680
|
+
sage: v = stats.TimeSeries([1,2,-5]); v
|
|
681
|
+
[1.0000, 2.0000, -5.0000]
|
|
682
|
+
sage: v.extend([-3.5, 2])
|
|
683
|
+
sage: v
|
|
684
|
+
[1.0000, 2.0000, -5.0000, -3.5000, 2.0000]
|
|
685
|
+
"""
|
|
686
|
+
if not isinstance(right, TimeSeries):
|
|
687
|
+
right = TimeSeries(right)
|
|
688
|
+
if not right:
|
|
689
|
+
return
|
|
690
|
+
cdef TimeSeries T = right
|
|
691
|
+
cdef double* z = <double*> sig_malloc(sizeof(double)*(self._length + T._length))
|
|
692
|
+
if z == NULL:
|
|
693
|
+
raise MemoryError
|
|
694
|
+
memcpy(z, self._values, sizeof(double)*self._length)
|
|
695
|
+
memcpy(z + self._length, T._values, sizeof(double)*T._length)
|
|
696
|
+
sig_free(self._values)
|
|
697
|
+
self._values = z
|
|
698
|
+
self._length = self._length + T._length
|
|
699
|
+
|
|
700
|
+
def list(self):
|
|
701
|
+
r"""
|
|
702
|
+
Return list of elements of ``self``.
|
|
703
|
+
|
|
704
|
+
EXAMPLES::
|
|
705
|
+
|
|
706
|
+
sage: v = stats.TimeSeries([1,-4,3,-2.5,-4,3])
|
|
707
|
+
sage: v.list()
|
|
708
|
+
[1.0, -4.0, 3.0, -2.5, -4.0, 3.0]
|
|
709
|
+
"""
|
|
710
|
+
cdef Py_ssize_t i
|
|
711
|
+
return [self._values[i] for i in range(self._length)]
|
|
712
|
+
|
|
713
|
+
def log(self):
|
|
714
|
+
r"""
|
|
715
|
+
Return new time series got by taking the logarithms of all the
|
|
716
|
+
terms in the time series.
|
|
717
|
+
|
|
718
|
+
OUTPUT: a new time series
|
|
719
|
+
|
|
720
|
+
EXAMPLES:
|
|
721
|
+
|
|
722
|
+
We exponentiate then log a time series and get back
|
|
723
|
+
the original series::
|
|
724
|
+
|
|
725
|
+
sage: v = stats.TimeSeries([1,-4,3,-2.5,-4,3]); v
|
|
726
|
+
[1.0000, -4.0000, 3.0000, -2.5000, -4.0000, 3.0000]
|
|
727
|
+
sage: v.exp()
|
|
728
|
+
[2.7183, 0.0183, 20.0855, 0.0821, 0.0183, 20.0855]
|
|
729
|
+
sage: v.exp().log()
|
|
730
|
+
[1.0000, -4.0000, 3.0000, -2.5000, -4.0000, 3.0000]
|
|
731
|
+
|
|
732
|
+
Log of 0 gives ``-inf``::
|
|
733
|
+
|
|
734
|
+
sage: stats.TimeSeries([1,0,3]).log()[1]
|
|
735
|
+
-inf
|
|
736
|
+
"""
|
|
737
|
+
cdef Py_ssize_t i
|
|
738
|
+
cdef TimeSeries t = new_time_series(self._length)
|
|
739
|
+
for i from 0 <= i < self._length:
|
|
740
|
+
t._values[i] = log(self._values[i])
|
|
741
|
+
return t
|
|
742
|
+
|
|
743
|
+
def exp(self):
|
|
744
|
+
r"""
|
|
745
|
+
Return new time series got by applying the exponential map to
|
|
746
|
+
all the terms in the time series.
|
|
747
|
+
|
|
748
|
+
OUTPUT: a new time series
|
|
749
|
+
|
|
750
|
+
EXAMPLES::
|
|
751
|
+
|
|
752
|
+
sage: v = stats.TimeSeries([1..5]); v
|
|
753
|
+
[1.0000, 2.0000, 3.0000, 4.0000, 5.0000]
|
|
754
|
+
sage: v.exp()
|
|
755
|
+
[2.7183, 7.3891, 20.0855, 54.5982, 148.4132]
|
|
756
|
+
sage: v.exp().log()
|
|
757
|
+
[1.0000, 2.0000, 3.0000, 4.0000, 5.0000]
|
|
758
|
+
"""
|
|
759
|
+
cdef Py_ssize_t i
|
|
760
|
+
cdef TimeSeries t = new_time_series(self._length)
|
|
761
|
+
for i from 0 <= i < self._length:
|
|
762
|
+
t._values[i] = exp(self._values[i])
|
|
763
|
+
return t
|
|
764
|
+
|
|
765
|
+
def abs(self):
|
|
766
|
+
r"""
|
|
767
|
+
Return new time series got by replacing all entries
|
|
768
|
+
of ``self`` by their absolute value.
|
|
769
|
+
|
|
770
|
+
OUTPUT: a new time series
|
|
771
|
+
|
|
772
|
+
EXAMPLES::
|
|
773
|
+
|
|
774
|
+
sage: v = stats.TimeSeries([1,3.1908439,-4,5.93932])
|
|
775
|
+
sage: v
|
|
776
|
+
[1.0000, 3.1908, -4.0000, 5.9393]
|
|
777
|
+
sage: v.abs()
|
|
778
|
+
[1.0000, 3.1908, 4.0000, 5.9393]
|
|
779
|
+
"""
|
|
780
|
+
cdef Py_ssize_t i
|
|
781
|
+
cdef TimeSeries t = new_time_series(self._length)
|
|
782
|
+
for i from 0 <= i < self._length:
|
|
783
|
+
t._values[i] = self._values[i] if self._values[i] >= 0 else -self._values[i]
|
|
784
|
+
return t
|
|
785
|
+
|
|
786
|
+
def diffs(self, Py_ssize_t k=1):
|
|
787
|
+
r"""
|
|
788
|
+
Return the new time series got by taking the differences of
|
|
789
|
+
successive terms in the time series. So if ``self`` is the time
|
|
790
|
+
series `X_0, X_1, X_2, \dots`, then this function outputs the
|
|
791
|
+
series `X_1 - X_0, X_2 - X_1, \dots`. The output series has one
|
|
792
|
+
less term than the input series. If the optional parameter
|
|
793
|
+
`k` is given, return `X_k - X_0, X_{2k} - X_k, \dots`.
|
|
794
|
+
|
|
795
|
+
INPUT:
|
|
796
|
+
|
|
797
|
+
- ``k`` -- positive integer (default: 1)
|
|
798
|
+
|
|
799
|
+
OUTPUT: a new time series
|
|
800
|
+
|
|
801
|
+
EXAMPLES::
|
|
802
|
+
|
|
803
|
+
sage: v = stats.TimeSeries([5,4,1.3,2,8]); v
|
|
804
|
+
[5.0000, 4.0000, 1.3000, 2.0000, 8.0000]
|
|
805
|
+
sage: v.diffs()
|
|
806
|
+
[-1.0000, -2.7000, 0.7000, 6.0000]
|
|
807
|
+
"""
|
|
808
|
+
if k != 1:
|
|
809
|
+
return self.scale_time(k).diffs()
|
|
810
|
+
cdef Py_ssize_t i
|
|
811
|
+
cdef TimeSeries t = new_time_series(self._length - 1)
|
|
812
|
+
for i from 1 <= i < self._length:
|
|
813
|
+
t._values[i-1] = self._values[i] - self._values[i-1]
|
|
814
|
+
return t
|
|
815
|
+
|
|
816
|
+
def scale_time(self, Py_ssize_t k):
|
|
817
|
+
r"""
|
|
818
|
+
Return the new time series at scale ``k``. If the input
|
|
819
|
+
time series is `X_0, X_1, X_2, \dots`, then this function
|
|
820
|
+
returns the shorter time series `X_0, X_k, X_{2k}, \dots`.
|
|
821
|
+
|
|
822
|
+
INPUT:
|
|
823
|
+
|
|
824
|
+
- ``k`` -- positive integer
|
|
825
|
+
|
|
826
|
+
OUTPUT: a new time series
|
|
827
|
+
|
|
828
|
+
EXAMPLES::
|
|
829
|
+
|
|
830
|
+
sage: v = stats.TimeSeries([5,4,1.3,2,8,10,3,-5]); v
|
|
831
|
+
[5.0000, 4.0000, 1.3000, 2.0000, 8.0000, 10.0000, 3.0000, -5.0000]
|
|
832
|
+
sage: v.scale_time(1)
|
|
833
|
+
[5.0000, 4.0000, 1.3000, 2.0000, 8.0000, 10.0000, 3.0000, -5.0000]
|
|
834
|
+
sage: v.scale_time(2)
|
|
835
|
+
[5.0000, 1.3000, 8.0000, 3.0000]
|
|
836
|
+
sage: v.scale_time(3)
|
|
837
|
+
[5.0000, 2.0000]
|
|
838
|
+
sage: v.scale_time(10)
|
|
839
|
+
[]
|
|
840
|
+
|
|
841
|
+
A series of odd length::
|
|
842
|
+
|
|
843
|
+
sage: v = stats.TimeSeries([1..5]); v
|
|
844
|
+
[1.0000, 2.0000, 3.0000, 4.0000, 5.0000]
|
|
845
|
+
sage: v.scale_time(2)
|
|
846
|
+
[1.0000, 3.0000, 5.0000]
|
|
847
|
+
|
|
848
|
+
TESTS::
|
|
849
|
+
|
|
850
|
+
sage: v.scale_time(0)
|
|
851
|
+
Traceback (most recent call last):
|
|
852
|
+
...
|
|
853
|
+
ValueError: k must be positive
|
|
854
|
+
sage: v.scale_time(-1)
|
|
855
|
+
Traceback (most recent call last):
|
|
856
|
+
...
|
|
857
|
+
ValueError: k must be positive
|
|
858
|
+
"""
|
|
859
|
+
if k <= 0:
|
|
860
|
+
raise ValueError("k must be positive")
|
|
861
|
+
|
|
862
|
+
cdef Py_ssize_t i, n
|
|
863
|
+
n = self._length/k
|
|
864
|
+
if self._length % 2:
|
|
865
|
+
n += 1
|
|
866
|
+
cdef TimeSeries t = new_time_series(n) # in C / is floor division.
|
|
867
|
+
for i from 0 <= i < n:
|
|
868
|
+
t._values[i] = self._values[i*k]
|
|
869
|
+
return t
|
|
870
|
+
|
|
871
|
+
cpdef rescale(self, double s):
|
|
872
|
+
r"""
|
|
873
|
+
Change ``self`` by multiplying every value in the series by ``s``.
|
|
874
|
+
|
|
875
|
+
INPUT:
|
|
876
|
+
|
|
877
|
+
- ``s`` -- a float
|
|
878
|
+
|
|
879
|
+
EXAMPLES::
|
|
880
|
+
|
|
881
|
+
sage: v = stats.TimeSeries([5,4,1.3,2,8,10,3,-5]); v
|
|
882
|
+
[5.0000, 4.0000, 1.3000, 2.0000, 8.0000, 10.0000, 3.0000, -5.0000]
|
|
883
|
+
sage: v.rescale(0.5)
|
|
884
|
+
sage: v
|
|
885
|
+
[2.5000, 2.0000, 0.6500, 1.0000, 4.0000, 5.0000, 1.5000, -2.5000]
|
|
886
|
+
"""
|
|
887
|
+
for i from 0 <= i < self._length:
|
|
888
|
+
self._values[i] = self._values[i] * s
|
|
889
|
+
|
|
890
|
+
def scale(self, double s):
|
|
891
|
+
r"""
|
|
892
|
+
Return new time series obtained by multiplying every value in the
|
|
893
|
+
series by ``s``.
|
|
894
|
+
|
|
895
|
+
INPUT:
|
|
896
|
+
|
|
897
|
+
- ``s`` -- a float
|
|
898
|
+
|
|
899
|
+
OUTPUT: a new time series with all values multiplied by ``s``
|
|
900
|
+
|
|
901
|
+
EXAMPLES::
|
|
902
|
+
|
|
903
|
+
sage: v = stats.TimeSeries([5,4,1.3,2,8,10,3,-5]); v
|
|
904
|
+
[5.0000, 4.0000, 1.3000, 2.0000, 8.0000, 10.0000, 3.0000, -5.0000]
|
|
905
|
+
sage: v.scale(0.5)
|
|
906
|
+
[2.5000, 2.0000, 0.6500, 1.0000, 4.0000, 5.0000, 1.5000, -2.5000]
|
|
907
|
+
"""
|
|
908
|
+
cdef TimeSeries t = new_time_series(self._length)
|
|
909
|
+
for i from 0 <= i < self._length:
|
|
910
|
+
t._values[i] = self._values[i] * s
|
|
911
|
+
return t
|
|
912
|
+
|
|
913
|
+
def add_scalar(self, double s):
|
|
914
|
+
r"""
|
|
915
|
+
Return new time series obtained by adding a scalar to every
|
|
916
|
+
value in the series.
|
|
917
|
+
|
|
918
|
+
.. NOTE::
|
|
919
|
+
|
|
920
|
+
To add componentwise, use the :meth:`add_entries` method.
|
|
921
|
+
|
|
922
|
+
INPUT:
|
|
923
|
+
|
|
924
|
+
- ``s`` -- a float
|
|
925
|
+
|
|
926
|
+
OUTPUT: a new time series with ``s`` added to all values
|
|
927
|
+
|
|
928
|
+
EXAMPLES::
|
|
929
|
+
|
|
930
|
+
sage: v = stats.TimeSeries([5,4,1.3,2,8,10,3,-5]); v
|
|
931
|
+
[5.0000, 4.0000, 1.3000, 2.0000, 8.0000, 10.0000, 3.0000, -5.0000]
|
|
932
|
+
sage: v.add_scalar(0.5)
|
|
933
|
+
[5.5000, 4.5000, 1.8000, 2.5000, 8.5000, 10.5000, 3.5000, -4.5000]
|
|
934
|
+
"""
|
|
935
|
+
cdef TimeSeries t = new_time_series(self._length)
|
|
936
|
+
for i from 0 <= i < self._length:
|
|
937
|
+
t._values[i] = self._values[i] + s
|
|
938
|
+
return t
|
|
939
|
+
|
|
940
|
+
def add_entries(self, t):
|
|
941
|
+
r"""
|
|
942
|
+
Add corresponding entries of ``self`` and ``t`` together,
|
|
943
|
+
extending either ``self`` or ``t`` by 0s if they do
|
|
944
|
+
not have the same length.
|
|
945
|
+
|
|
946
|
+
.. NOTE::
|
|
947
|
+
|
|
948
|
+
To add a single number to the entries of a time series,
|
|
949
|
+
use the ``add_scalar`` method.
|
|
950
|
+
|
|
951
|
+
INPUT:
|
|
952
|
+
|
|
953
|
+
- ``t`` -- a time series
|
|
954
|
+
|
|
955
|
+
OUTPUT:
|
|
956
|
+
|
|
957
|
+
A time series with length the maximum of the lengths of
|
|
958
|
+
``self`` and ``t``.
|
|
959
|
+
|
|
960
|
+
EXAMPLES::
|
|
961
|
+
|
|
962
|
+
sage: v = stats.TimeSeries([1,2,-5]); v
|
|
963
|
+
[1.0000, 2.0000, -5.0000]
|
|
964
|
+
sage: v.add_entries([3,4])
|
|
965
|
+
[4.0000, 6.0000, -5.0000]
|
|
966
|
+
sage: v.add_entries(v)
|
|
967
|
+
[2.0000, 4.0000, -10.0000]
|
|
968
|
+
sage: v.add_entries([3,4,7,18.5])
|
|
969
|
+
[4.0000, 6.0000, 2.0000, 18.5000]
|
|
970
|
+
"""
|
|
971
|
+
if not isinstance(t, TimeSeries):
|
|
972
|
+
t = TimeSeries(t)
|
|
973
|
+
cdef Py_ssize_t i, n
|
|
974
|
+
cdef TimeSeries T = t, shorter, longer
|
|
975
|
+
if self._length > T._length:
|
|
976
|
+
shorter = T
|
|
977
|
+
longer = self
|
|
978
|
+
else:
|
|
979
|
+
shorter = self
|
|
980
|
+
longer = T
|
|
981
|
+
|
|
982
|
+
n = longer._length
|
|
983
|
+
cdef TimeSeries v = new_time_series(n)
|
|
984
|
+
|
|
985
|
+
# Iterate up to the length of the shorter one
|
|
986
|
+
for i from 0 <= i < shorter._length:
|
|
987
|
+
v._values[i] = shorter._values[i] + longer._values[i]
|
|
988
|
+
|
|
989
|
+
# Copy over the rest of the values
|
|
990
|
+
if shorter._length != n:
|
|
991
|
+
memcpy(v._values + shorter._length,
|
|
992
|
+
longer._values + shorter._length,
|
|
993
|
+
sizeof(double)*(v._length - shorter._length))
|
|
994
|
+
|
|
995
|
+
return v
|
|
996
|
+
|
|
997
|
+
def show(self, *args, **kwds):
|
|
998
|
+
r"""
|
|
999
|
+
Return a plot of this time series.
|
|
1000
|
+
|
|
1001
|
+
This is an alias of :meth:`plot`.
|
|
1002
|
+
|
|
1003
|
+
EXAMPLES:
|
|
1004
|
+
|
|
1005
|
+
Draw a plot of a time series::
|
|
1006
|
+
|
|
1007
|
+
sage: stats.TimeSeries([1..10]).show() # needs sage.plot
|
|
1008
|
+
Graphics object consisting of 1 graphics primitive
|
|
1009
|
+
"""
|
|
1010
|
+
return self.plot(*args, **kwds)
|
|
1011
|
+
|
|
1012
|
+
def plot(self, Py_ssize_t plot_points=1000, points=False, **kwds):
|
|
1013
|
+
r"""
|
|
1014
|
+
Return a plot of this time series.
|
|
1015
|
+
|
|
1016
|
+
The plot shows a line or points through
|
|
1017
|
+
`(i,T(i))`, where `i` ranges over nonnegative integers up to the
|
|
1018
|
+
length of ``self``.
|
|
1019
|
+
|
|
1020
|
+
INPUT:
|
|
1021
|
+
|
|
1022
|
+
- ``plot_points`` -- (default: 1000) 0 or positive integer. Only
|
|
1023
|
+
plot the given number of equally spaced points in the time series.
|
|
1024
|
+
If 0, plot all points.
|
|
1025
|
+
|
|
1026
|
+
- ``points`` -- boolean (default: ``False``); if ``True``, return just
|
|
1027
|
+
the points of the time series
|
|
1028
|
+
|
|
1029
|
+
- ``**kwds`` -- passed to the line or point command
|
|
1030
|
+
|
|
1031
|
+
EXAMPLES::
|
|
1032
|
+
|
|
1033
|
+
sage: # needs sage.plot
|
|
1034
|
+
sage: v = stats.TimeSeries([5,4,1.3,2,8,10,3,-5]); v
|
|
1035
|
+
[5.0000, 4.0000, 1.3000, 2.0000, 8.0000, 10.0000, 3.0000, -5.0000]
|
|
1036
|
+
sage: v.plot()
|
|
1037
|
+
Graphics object consisting of 1 graphics primitive
|
|
1038
|
+
sage: v.plot(points=True)
|
|
1039
|
+
Graphics object consisting of 1 graphics primitive
|
|
1040
|
+
sage: v.plot() + v.plot(points=True, rgbcolor='red')
|
|
1041
|
+
Graphics object consisting of 2 graphics primitives
|
|
1042
|
+
sage: v.plot() + v.plot(points=True, rgbcolor='red', pointsize=50)
|
|
1043
|
+
Graphics object consisting of 2 graphics primitives
|
|
1044
|
+
"""
|
|
1045
|
+
from sage.plot.all import line, point
|
|
1046
|
+
cdef Py_ssize_t s
|
|
1047
|
+
|
|
1048
|
+
if self._length < plot_points:
|
|
1049
|
+
plot_points = 0
|
|
1050
|
+
|
|
1051
|
+
if plot_points > 0:
|
|
1052
|
+
s = self._length/plot_points
|
|
1053
|
+
if plot_points <= 0:
|
|
1054
|
+
raise ValueError("plot_points must be a positive integer")
|
|
1055
|
+
v = self.scale_time(s).list()[:plot_points]
|
|
1056
|
+
else:
|
|
1057
|
+
s = 1
|
|
1058
|
+
v = self.list()
|
|
1059
|
+
w = [(i * s, y) for i,y in enumerate(v)]
|
|
1060
|
+
if points:
|
|
1061
|
+
L = point(w, **kwds)
|
|
1062
|
+
else:
|
|
1063
|
+
L = line(w, **kwds)
|
|
1064
|
+
L.axes_range(ymin=min(v), ymax=max(v), xmin=0, xmax=len(v)*s)
|
|
1065
|
+
return L
|
|
1066
|
+
|
|
1067
|
+
def simple_moving_average(self, Py_ssize_t k):
|
|
1068
|
+
r"""
|
|
1069
|
+
Return the moving average time series over the last `k` time units.
|
|
1070
|
+
|
|
1071
|
+
Assumes the input time series was constant with its starting value
|
|
1072
|
+
for negative time. The `t`-th step of the output is the sum of
|
|
1073
|
+
the previous `k - 1` steps of ``self`` and the `k`-th step
|
|
1074
|
+
divided by `k`. Thus `k` values are averaged at each point.
|
|
1075
|
+
|
|
1076
|
+
INPUT:
|
|
1077
|
+
|
|
1078
|
+
- ``k`` -- positive integer
|
|
1079
|
+
|
|
1080
|
+
OUTPUT: a time series with the same number of steps as ``self``
|
|
1081
|
+
|
|
1082
|
+
EXAMPLES::
|
|
1083
|
+
|
|
1084
|
+
sage: v = stats.TimeSeries([1,1,1,2,3]); v
|
|
1085
|
+
[1.0000, 1.0000, 1.0000, 2.0000, 3.0000]
|
|
1086
|
+
sage: v.simple_moving_average(0)
|
|
1087
|
+
[1.0000, 1.0000, 1.0000, 2.0000, 3.0000]
|
|
1088
|
+
sage: v.simple_moving_average(1)
|
|
1089
|
+
[1.0000, 1.0000, 1.0000, 2.0000, 3.0000]
|
|
1090
|
+
sage: v.simple_moving_average(2)
|
|
1091
|
+
[1.0000, 1.0000, 1.0000, 1.5000, 2.5000]
|
|
1092
|
+
sage: v.simple_moving_average(3)
|
|
1093
|
+
[1.0000, 1.0000, 1.0000, 1.3333, 2.0000]
|
|
1094
|
+
"""
|
|
1095
|
+
if k == 0 or k == 1:
|
|
1096
|
+
return self.__copy__()
|
|
1097
|
+
if k <= 0:
|
|
1098
|
+
raise ValueError("k must be positive")
|
|
1099
|
+
cdef Py_ssize_t i
|
|
1100
|
+
cdef TimeSeries t = new_time_series(self._length)
|
|
1101
|
+
if self._length == 0:
|
|
1102
|
+
return t
|
|
1103
|
+
|
|
1104
|
+
cdef double s = self._values[0] * k
|
|
1105
|
+
for i from 0 <= i < self._length:
|
|
1106
|
+
if i >= k:
|
|
1107
|
+
s -= self._values[i-k]
|
|
1108
|
+
else:
|
|
1109
|
+
s -= self._values[0]
|
|
1110
|
+
# I have a slight concern about accumulated rounding error given how
|
|
1111
|
+
# this algorithm adds and subtracts.
|
|
1112
|
+
s += self._values[i]
|
|
1113
|
+
t._values[i] = s/k
|
|
1114
|
+
return t
|
|
1115
|
+
|
|
1116
|
+
def exponential_moving_average(self, double alpha):
|
|
1117
|
+
r"""
|
|
1118
|
+
Return the exponential moving average time series.
|
|
1119
|
+
|
|
1120
|
+
Assumes the input time series was constant with its starting
|
|
1121
|
+
value for negative time. The `t`-th step of the output is the
|
|
1122
|
+
sum of the previous `k-1` steps of ``self`` and the `k`-th
|
|
1123
|
+
step divided by `k`.
|
|
1124
|
+
|
|
1125
|
+
The 0-th term is formally undefined, so we define it to be 0,
|
|
1126
|
+
and we define the first term to be ``self[0]``.
|
|
1127
|
+
|
|
1128
|
+
INPUT:
|
|
1129
|
+
|
|
1130
|
+
- ``alpha`` -- float; a smoothing factor with ``0 <= alpha <= 1``
|
|
1131
|
+
|
|
1132
|
+
OUTPUT: a time series with the same number of steps as ``self``
|
|
1133
|
+
|
|
1134
|
+
EXAMPLES::
|
|
1135
|
+
|
|
1136
|
+
sage: v = stats.TimeSeries([1,1,1,2,3]); v
|
|
1137
|
+
[1.0000, 1.0000, 1.0000, 2.0000, 3.0000]
|
|
1138
|
+
sage: v.exponential_moving_average(0)
|
|
1139
|
+
[0.0000, 1.0000, 1.0000, 1.0000, 1.0000]
|
|
1140
|
+
sage: v.exponential_moving_average(1)
|
|
1141
|
+
[0.0000, 1.0000, 1.0000, 1.0000, 2.0000]
|
|
1142
|
+
sage: v.exponential_moving_average(0.5)
|
|
1143
|
+
[0.0000, 1.0000, 1.0000, 1.0000, 1.5000]
|
|
1144
|
+
|
|
1145
|
+
Some more examples::
|
|
1146
|
+
|
|
1147
|
+
sage: v = stats.TimeSeries([1,2,3,4,5])
|
|
1148
|
+
sage: v.exponential_moving_average(1)
|
|
1149
|
+
[0.0000, 1.0000, 2.0000, 3.0000, 4.0000]
|
|
1150
|
+
sage: v.exponential_moving_average(0)
|
|
1151
|
+
[0.0000, 1.0000, 1.0000, 1.0000, 1.0000]
|
|
1152
|
+
"""
|
|
1153
|
+
if alpha < 0 or alpha > 1:
|
|
1154
|
+
raise ValueError("alpha must be between 0 and 1")
|
|
1155
|
+
cdef Py_ssize_t i
|
|
1156
|
+
cdef TimeSeries t = new_time_series(self._length)
|
|
1157
|
+
if self._length == 0:
|
|
1158
|
+
return t
|
|
1159
|
+
t._values[0] = 0
|
|
1160
|
+
if self._length == 1:
|
|
1161
|
+
return t
|
|
1162
|
+
t._values[1] = self._values[0]
|
|
1163
|
+
for i from 2 <= i < self._length:
|
|
1164
|
+
t._values[i] = alpha * self._values[i-1] + (1-alpha) *t._values[i-1]
|
|
1165
|
+
return t
|
|
1166
|
+
|
|
1167
|
+
def sums(self, double s=0):
|
|
1168
|
+
r"""
|
|
1169
|
+
Return the new time series got by taking the running partial
|
|
1170
|
+
sums of the terms of this time series.
|
|
1171
|
+
|
|
1172
|
+
INPUT:
|
|
1173
|
+
|
|
1174
|
+
- ``s`` -- starting value for partial sums
|
|
1175
|
+
|
|
1176
|
+
OUTPUT: a time series
|
|
1177
|
+
|
|
1178
|
+
EXAMPLES::
|
|
1179
|
+
|
|
1180
|
+
sage: v = stats.TimeSeries([1,1,1,2,3]); v
|
|
1181
|
+
[1.0000, 1.0000, 1.0000, 2.0000, 3.0000]
|
|
1182
|
+
sage: v.sums()
|
|
1183
|
+
[1.0000, 2.0000, 3.0000, 5.0000, 8.0000]
|
|
1184
|
+
"""
|
|
1185
|
+
cdef Py_ssize_t i
|
|
1186
|
+
cdef TimeSeries t = new_time_series(self._length)
|
|
1187
|
+
for i from 0 <= i < self._length:
|
|
1188
|
+
s += self._values[i]
|
|
1189
|
+
t._values[i] = s
|
|
1190
|
+
return t
|
|
1191
|
+
|
|
1192
|
+
cpdef double sum(self) noexcept:
|
|
1193
|
+
r"""
|
|
1194
|
+
Return the sum of all the entries of ``self``.
|
|
1195
|
+
|
|
1196
|
+
If ``self`` has length 0, returns 0.
|
|
1197
|
+
|
|
1198
|
+
OUTPUT: double
|
|
1199
|
+
|
|
1200
|
+
EXAMPLES::
|
|
1201
|
+
|
|
1202
|
+
sage: v = stats.TimeSeries([1,1,1,2,3]); v
|
|
1203
|
+
[1.0000, 1.0000, 1.0000, 2.0000, 3.0000]
|
|
1204
|
+
sage: v.sum()
|
|
1205
|
+
8.0
|
|
1206
|
+
"""
|
|
1207
|
+
cdef double s = 0
|
|
1208
|
+
cdef Py_ssize_t i
|
|
1209
|
+
for i from 0 <= i < self._length:
|
|
1210
|
+
s += self._values[i]
|
|
1211
|
+
return s
|
|
1212
|
+
|
|
1213
|
+
def prod(self):
|
|
1214
|
+
r"""
|
|
1215
|
+
Return the product of all the entries of ``self``.
|
|
1216
|
+
|
|
1217
|
+
If ``self`` has length 0, returns 1.
|
|
1218
|
+
|
|
1219
|
+
OUTPUT: double
|
|
1220
|
+
|
|
1221
|
+
EXAMPLES::
|
|
1222
|
+
|
|
1223
|
+
sage: v = stats.TimeSeries([1,1,1,2,3]); v
|
|
1224
|
+
[1.0000, 1.0000, 1.0000, 2.0000, 3.0000]
|
|
1225
|
+
sage: v.prod()
|
|
1226
|
+
6.0
|
|
1227
|
+
"""
|
|
1228
|
+
cdef double s = 1
|
|
1229
|
+
cdef Py_ssize_t i
|
|
1230
|
+
for i from 0 <= i < self._length:
|
|
1231
|
+
s *= self._values[i]
|
|
1232
|
+
return s
|
|
1233
|
+
|
|
1234
|
+
def mean(self):
|
|
1235
|
+
r"""
|
|
1236
|
+
Return the mean (average) of the elements of ``self``.
|
|
1237
|
+
|
|
1238
|
+
OUTPUT: double
|
|
1239
|
+
|
|
1240
|
+
EXAMPLES::
|
|
1241
|
+
|
|
1242
|
+
sage: v = stats.TimeSeries([1,1,1,2,3]); v
|
|
1243
|
+
[1.0000, 1.0000, 1.0000, 2.0000, 3.0000]
|
|
1244
|
+
sage: v.mean()
|
|
1245
|
+
1.6
|
|
1246
|
+
"""
|
|
1247
|
+
return self.sum() / self._length
|
|
1248
|
+
|
|
1249
|
+
def pow(self, double k):
|
|
1250
|
+
r"""
|
|
1251
|
+
Return a new time series with all elements of ``self`` raised to the
|
|
1252
|
+
`k`-th power.
|
|
1253
|
+
|
|
1254
|
+
INPUT:
|
|
1255
|
+
|
|
1256
|
+
- ``k`` -- a float
|
|
1257
|
+
|
|
1258
|
+
OUTPUT: a time series
|
|
1259
|
+
|
|
1260
|
+
EXAMPLES::
|
|
1261
|
+
|
|
1262
|
+
sage: v = stats.TimeSeries([1,1,1,2,3]); v
|
|
1263
|
+
[1.0000, 1.0000, 1.0000, 2.0000, 3.0000]
|
|
1264
|
+
sage: v.pow(2)
|
|
1265
|
+
[1.0000, 1.0000, 1.0000, 4.0000, 9.0000]
|
|
1266
|
+
"""
|
|
1267
|
+
cdef Py_ssize_t i
|
|
1268
|
+
cdef TimeSeries t = new_time_series(self._length)
|
|
1269
|
+
for i from 0 <= i < self._length:
|
|
1270
|
+
t._values[i] = pow(self._values[i], k)
|
|
1271
|
+
return t
|
|
1272
|
+
|
|
1273
|
+
def moment(self, int k):
|
|
1274
|
+
r"""
|
|
1275
|
+
Return the `k`-th moment of ``self``, which is just the
|
|
1276
|
+
mean of the `k`-th powers of the elements of ``self``.
|
|
1277
|
+
|
|
1278
|
+
INPUT:
|
|
1279
|
+
|
|
1280
|
+
- ``k`` -- positive integer
|
|
1281
|
+
|
|
1282
|
+
OUTPUT: double
|
|
1283
|
+
|
|
1284
|
+
EXAMPLES::
|
|
1285
|
+
|
|
1286
|
+
sage: v = stats.TimeSeries([1,1,1,2,3]); v
|
|
1287
|
+
[1.0000, 1.0000, 1.0000, 2.0000, 3.0000]
|
|
1288
|
+
sage: v.moment(1)
|
|
1289
|
+
1.6
|
|
1290
|
+
sage: v.moment(2)
|
|
1291
|
+
3.2
|
|
1292
|
+
"""
|
|
1293
|
+
if k <= 0:
|
|
1294
|
+
raise ValueError("k must be positive")
|
|
1295
|
+
if k == 1:
|
|
1296
|
+
return self.mean()
|
|
1297
|
+
cdef double s = 0
|
|
1298
|
+
cdef Py_ssize_t i
|
|
1299
|
+
for i from 0 <= i < self._length:
|
|
1300
|
+
s += pow(self._values[i], k)
|
|
1301
|
+
return s / self._length
|
|
1302
|
+
|
|
1303
|
+
def central_moment(self, int k):
|
|
1304
|
+
r"""
|
|
1305
|
+
Return the `k`-th central moment of ``self``, which is just the mean
|
|
1306
|
+
of the `k`-th powers of the differences ``self[i] - mu``, where ``mu`` is
|
|
1307
|
+
the mean of ``self``.
|
|
1308
|
+
|
|
1309
|
+
INPUT:
|
|
1310
|
+
|
|
1311
|
+
- ``k`` -- positive integer
|
|
1312
|
+
|
|
1313
|
+
OUTPUT: double
|
|
1314
|
+
|
|
1315
|
+
EXAMPLES::
|
|
1316
|
+
|
|
1317
|
+
sage: v = stats.TimeSeries([1,2,3])
|
|
1318
|
+
sage: v.central_moment(2)
|
|
1319
|
+
0.6666666666666666
|
|
1320
|
+
|
|
1321
|
+
Note that the central moment is different from the moment
|
|
1322
|
+
here, since the mean is not `0`::
|
|
1323
|
+
|
|
1324
|
+
sage: v.moment(2) # doesn't subtract off mean
|
|
1325
|
+
4.666666666666667
|
|
1326
|
+
|
|
1327
|
+
We compute the central moment directly::
|
|
1328
|
+
|
|
1329
|
+
sage: mu = v.mean(); mu
|
|
1330
|
+
2.0
|
|
1331
|
+
sage: ((1-mu)^2 + (2-mu)^2 + (3-mu)^2) / 3
|
|
1332
|
+
0.6666666666666666
|
|
1333
|
+
"""
|
|
1334
|
+
if k == 1:
|
|
1335
|
+
return float(0)
|
|
1336
|
+
mu = self.mean()
|
|
1337
|
+
# We could make this slightly faster by doing the add scalar
|
|
1338
|
+
# and moment calculation together. But that would be nasty.
|
|
1339
|
+
return self.add_scalar(-mu).moment(k)
|
|
1340
|
+
|
|
1341
|
+
def covariance(self, TimeSeries other):
|
|
1342
|
+
r"""
|
|
1343
|
+
Return the covariance of the time series ``self`` and ``other``.
|
|
1344
|
+
|
|
1345
|
+
INPUT:
|
|
1346
|
+
|
|
1347
|
+
- ``self``, ``other`` -- time series
|
|
1348
|
+
|
|
1349
|
+
Whichever time series has more terms is truncated.
|
|
1350
|
+
|
|
1351
|
+
EXAMPLES::
|
|
1352
|
+
|
|
1353
|
+
sage: v = stats.TimeSeries([1,-2,3]); w = stats.TimeSeries([4,5,-10])
|
|
1354
|
+
sage: v.covariance(w)
|
|
1355
|
+
-11.777777777777779
|
|
1356
|
+
"""
|
|
1357
|
+
cdef double mu = self.mean(), mu2 = other.mean()
|
|
1358
|
+
cdef double s = 0
|
|
1359
|
+
cdef Py_ssize_t i
|
|
1360
|
+
cdef Py_ssize_t n = min(self._length, other._length)
|
|
1361
|
+
for i from 0 <= i < n:
|
|
1362
|
+
s += (self._values[i] - mu)*(other._values[i] - mu2)
|
|
1363
|
+
return s / n
|
|
1364
|
+
# NOTE: There is also a formula
|
|
1365
|
+
# self._values[i]*other._values[i] - mu*mu2
|
|
1366
|
+
# but that seems less numerically stable (?), and when tested
|
|
1367
|
+
# was not noticeably faster.
|
|
1368
|
+
|
|
1369
|
+
def autocovariance(self, Py_ssize_t k=0):
|
|
1370
|
+
r"""
|
|
1371
|
+
Return the `k`-th autocovariance function `\gamma(k)` of ``self``.
|
|
1372
|
+
|
|
1373
|
+
This is the covariance of ``self`` with ``self`` shifted by `k`, i.e.,
|
|
1374
|
+
|
|
1375
|
+
.. MATH::
|
|
1376
|
+
|
|
1377
|
+
\left.
|
|
1378
|
+
\left( \sum_{t=0}^{n-k-1} (x_t - \mu)(x_{t + k} - \mu) \right)
|
|
1379
|
+
\right/ n,
|
|
1380
|
+
|
|
1381
|
+
where `n` is the length of ``self``.
|
|
1382
|
+
|
|
1383
|
+
Note the denominator of `n`, which gives a "better" sample
|
|
1384
|
+
estimator.
|
|
1385
|
+
|
|
1386
|
+
INPUT:
|
|
1387
|
+
|
|
1388
|
+
- ``k`` -- nonnegative integer (default: 0)
|
|
1389
|
+
|
|
1390
|
+
OUTPUT: float
|
|
1391
|
+
|
|
1392
|
+
EXAMPLES::
|
|
1393
|
+
|
|
1394
|
+
sage: v = stats.TimeSeries([13,8,15,4,4,12,11,7,14,12])
|
|
1395
|
+
sage: v.autocovariance(0)
|
|
1396
|
+
14.4
|
|
1397
|
+
sage: mu = v.mean(); sum([(a-mu)^2 for a in v])/len(v)
|
|
1398
|
+
14.4
|
|
1399
|
+
sage: v.autocovariance(1)
|
|
1400
|
+
-2.7
|
|
1401
|
+
sage: mu = v.mean()
|
|
1402
|
+
sage: sum((v[i]-mu)*(v[i+1]-mu) for i in range(len(v)-1))/len(v)
|
|
1403
|
+
-2.7
|
|
1404
|
+
sage: v.autocovariance(1)
|
|
1405
|
+
-2.7
|
|
1406
|
+
|
|
1407
|
+
We illustrate with a random sample that an independently and
|
|
1408
|
+
identically distributed distribution with zero mean and
|
|
1409
|
+
variance `\sigma^2` has autocovariance function `\gamma(h)`
|
|
1410
|
+
with `\gamma(0) = \sigma^2` and `\gamma(h) = 0` for `h\neq 0`. ::
|
|
1411
|
+
|
|
1412
|
+
sage: set_random_seed(0)
|
|
1413
|
+
sage: v = stats.TimeSeries(10^6)
|
|
1414
|
+
sage: v.randomize('normal', 0, 5)
|
|
1415
|
+
[3.3835, -2.0055, 1.7882, -2.9319, -4.6827 ...
|
|
1416
|
+
-5.1868, 9.2613, 0.9274, -6.2282, -8.7652]
|
|
1417
|
+
sage: v.autocovariance(0)
|
|
1418
|
+
24.95410689...
|
|
1419
|
+
sage: v.autocovariance(1)
|
|
1420
|
+
-0.00508390...
|
|
1421
|
+
sage: v.autocovariance(2)
|
|
1422
|
+
0.022056325...
|
|
1423
|
+
sage: v.autocovariance(3)
|
|
1424
|
+
-0.01902000...
|
|
1425
|
+
"""
|
|
1426
|
+
cdef double mu = self.mean()
|
|
1427
|
+
cdef double s = 0
|
|
1428
|
+
cdef Py_ssize_t i
|
|
1429
|
+
cdef Py_ssize_t n = self._length - k
|
|
1430
|
+
for i from 0 <= i < n:
|
|
1431
|
+
s += (self._values[i] - mu)*(self._values[i+k] - mu)
|
|
1432
|
+
return s / self._length
|
|
1433
|
+
|
|
1434
|
+
def correlation(self, TimeSeries other):
|
|
1435
|
+
r"""
|
|
1436
|
+
Return the correlation of ``self`` and ``other``, which is the
|
|
1437
|
+
covariance of ``self`` and ``other`` divided by the product of their
|
|
1438
|
+
standard deviation.
|
|
1439
|
+
|
|
1440
|
+
INPUT:
|
|
1441
|
+
|
|
1442
|
+
- ``self``, ``other`` -- time series
|
|
1443
|
+
|
|
1444
|
+
Whichever time series has more terms is truncated.
|
|
1445
|
+
|
|
1446
|
+
EXAMPLES::
|
|
1447
|
+
|
|
1448
|
+
sage: v = stats.TimeSeries([1,-2,3]); w = stats.TimeSeries([4,5,-10])
|
|
1449
|
+
sage: v.correlation(w)
|
|
1450
|
+
-0.558041609...
|
|
1451
|
+
sage: v.covariance(w)/(v.standard_deviation() * w.standard_deviation())
|
|
1452
|
+
-0.558041609...
|
|
1453
|
+
"""
|
|
1454
|
+
return self.covariance(other) / (self.standard_deviation() * other.standard_deviation())
|
|
1455
|
+
|
|
1456
|
+
def autocorrelation(self, Py_ssize_t k=1):
|
|
1457
|
+
r"""
|
|
1458
|
+
Return the `k`-th sample autocorrelation of this time series
|
|
1459
|
+
`x_i`.
|
|
1460
|
+
|
|
1461
|
+
Let `\mu` be the sample mean. Then the sample autocorrelation
|
|
1462
|
+
function is
|
|
1463
|
+
|
|
1464
|
+
.. MATH::
|
|
1465
|
+
|
|
1466
|
+
\frac{\sum_{t=0}^{n-k-1} (x_t - \mu)(x_{t+k} - \mu) }
|
|
1467
|
+
{\sum_{t=0}^{n-1} (x_t - \mu)^2}.
|
|
1468
|
+
|
|
1469
|
+
Note that the variance must be nonzero or you will get a
|
|
1470
|
+
:exc:`ZeroDivisionError`.
|
|
1471
|
+
|
|
1472
|
+
INPUT:
|
|
1473
|
+
|
|
1474
|
+
- ``k`` -- nonnegative integer (default: 1)
|
|
1475
|
+
|
|
1476
|
+
OUTPUT: a time series
|
|
1477
|
+
|
|
1478
|
+
EXAMPLES::
|
|
1479
|
+
|
|
1480
|
+
sage: v = stats.TimeSeries([13,8,15,4,4,12,11,7,14,12])
|
|
1481
|
+
sage: v.autocorrelation()
|
|
1482
|
+
-0.1875
|
|
1483
|
+
sage: v.autocorrelation(1)
|
|
1484
|
+
-0.1875
|
|
1485
|
+
sage: v.autocorrelation(0)
|
|
1486
|
+
1.0
|
|
1487
|
+
sage: v.autocorrelation(2)
|
|
1488
|
+
-0.20138888888888887
|
|
1489
|
+
sage: v.autocorrelation(3)
|
|
1490
|
+
0.18055555555555555
|
|
1491
|
+
|
|
1492
|
+
sage: stats.TimeSeries([1..1000]).autocorrelation()
|
|
1493
|
+
0.997
|
|
1494
|
+
"""
|
|
1495
|
+
return self.autocovariance(k) / self.variance(bias=True)
|
|
1496
|
+
|
|
1497
|
+
def variance(self, bias=False):
|
|
1498
|
+
r"""
|
|
1499
|
+
Return the variance of the elements of ``self``, which is the mean
|
|
1500
|
+
of the squares of the differences from the mean.
|
|
1501
|
+
|
|
1502
|
+
INPUT:
|
|
1503
|
+
|
|
1504
|
+
- ``bias`` -- boolean (default: ``False``); if ``False``, divide by
|
|
1505
|
+
``self.length() - 1`` instead of ``self.length()`` to give a less
|
|
1506
|
+
biased estimator for the variance.
|
|
1507
|
+
|
|
1508
|
+
OUTPUT: double
|
|
1509
|
+
|
|
1510
|
+
EXAMPLES::
|
|
1511
|
+
|
|
1512
|
+
sage: v = stats.TimeSeries([1,1,1,2,3]); v
|
|
1513
|
+
[1.0000, 1.0000, 1.0000, 2.0000, 3.0000]
|
|
1514
|
+
sage: v.variance()
|
|
1515
|
+
0.8
|
|
1516
|
+
sage: v.variance(bias=True)
|
|
1517
|
+
0.64
|
|
1518
|
+
|
|
1519
|
+
TESTS::
|
|
1520
|
+
|
|
1521
|
+
sage: stats.TimeSeries([1]).variance()
|
|
1522
|
+
0.0
|
|
1523
|
+
sage: stats.TimeSeries([]).variance()
|
|
1524
|
+
0.0
|
|
1525
|
+
"""
|
|
1526
|
+
if self._length <= 1:
|
|
1527
|
+
return float(0)
|
|
1528
|
+
cdef double mu = self.mean()
|
|
1529
|
+
cdef double s = 0
|
|
1530
|
+
cdef double a
|
|
1531
|
+
cdef Py_ssize_t i
|
|
1532
|
+
for i from 0 <= i < self._length:
|
|
1533
|
+
a = self._values[i] - mu
|
|
1534
|
+
s += a * a
|
|
1535
|
+
if bias:
|
|
1536
|
+
return s / self._length
|
|
1537
|
+
else:
|
|
1538
|
+
return s / (self._length - 1)
|
|
1539
|
+
|
|
1540
|
+
def standard_deviation(self, bias=False):
|
|
1541
|
+
r"""
|
|
1542
|
+
Return the standard deviation of the entries of ``self``.
|
|
1543
|
+
|
|
1544
|
+
INPUT:
|
|
1545
|
+
|
|
1546
|
+
- ``bias`` -- boolean (default: ``False``); if ``False``, divide by
|
|
1547
|
+
``self.length() - 1`` instead of ``self.length()`` to give a less
|
|
1548
|
+
biased estimator for the variance.
|
|
1549
|
+
|
|
1550
|
+
OUTPUT: double
|
|
1551
|
+
|
|
1552
|
+
EXAMPLES::
|
|
1553
|
+
|
|
1554
|
+
sage: v = stats.TimeSeries([1,1,1,2,3]); v
|
|
1555
|
+
[1.0000, 1.0000, 1.0000, 2.0000, 3.0000]
|
|
1556
|
+
sage: v.standard_deviation()
|
|
1557
|
+
0.8944271909...
|
|
1558
|
+
sage: v.standard_deviation(bias=True)
|
|
1559
|
+
0.8
|
|
1560
|
+
|
|
1561
|
+
TESTS::
|
|
1562
|
+
|
|
1563
|
+
sage: stats.TimeSeries([1]).standard_deviation()
|
|
1564
|
+
0.0
|
|
1565
|
+
sage: stats.TimeSeries([]).standard_deviation()
|
|
1566
|
+
0.0
|
|
1567
|
+
"""
|
|
1568
|
+
return sqrt(self.variance(bias=bias))
|
|
1569
|
+
|
|
1570
|
+
def range_statistic(self, b=None):
|
|
1571
|
+
r"""
|
|
1572
|
+
Return the rescaled range statistic `R/S` of ``self``, which is
|
|
1573
|
+
defined as follows (see Hurst 1951). If the optional
|
|
1574
|
+
parameter ``b`` is given, return the average of `R/S` range
|
|
1575
|
+
statistics of disjoint blocks of size ``b``.
|
|
1576
|
+
|
|
1577
|
+
Let `\sigma` be the standard deviation of the sequence of
|
|
1578
|
+
differences of ``self``, and let `Y_k` be the `k`-th term of ``self``.
|
|
1579
|
+
Let `n` be the number of terms of ``self``, and set
|
|
1580
|
+
`Z_k = Y_k - ((k+1)/n) \cdot Y_n`. Then
|
|
1581
|
+
|
|
1582
|
+
.. MATH::
|
|
1583
|
+
|
|
1584
|
+
R/S = \big( \max(Z_k) - \min(Z_k) \big) / \sigma
|
|
1585
|
+
|
|
1586
|
+
where the max and min are over all `Z_k`.
|
|
1587
|
+
Basically replacing `Y_k` by `Z_k` allows us to measure
|
|
1588
|
+
the difference from the line from the origin to `(n,Y_n)`.
|
|
1589
|
+
|
|
1590
|
+
INPUT:
|
|
1591
|
+
|
|
1592
|
+
- ``self`` -- a time series (*not* the series of differences)
|
|
1593
|
+
|
|
1594
|
+
- ``b`` -- integer (default: ``None``); if given instead divide the
|
|
1595
|
+
input time series up into ``j = floor(n/b)`` disjoint
|
|
1596
|
+
blocks, compute the `R/S` statistic for each block,
|
|
1597
|
+
and return the average of those `R/S` statistics.
|
|
1598
|
+
|
|
1599
|
+
OUTPUT: float
|
|
1600
|
+
|
|
1601
|
+
EXAMPLES:
|
|
1602
|
+
|
|
1603
|
+
Notice that if we make a Brownian motion random walk, there
|
|
1604
|
+
is no difference if we change the standard deviation. ::
|
|
1605
|
+
|
|
1606
|
+
sage: set_random_seed(0); stats.TimeSeries(10^6).randomize('normal').sums().range_statistic()
|
|
1607
|
+
1897.8392602...
|
|
1608
|
+
sage: set_random_seed(0); stats.TimeSeries(10^6).randomize('normal',0,100).sums().range_statistic()
|
|
1609
|
+
1897.8392602...
|
|
1610
|
+
"""
|
|
1611
|
+
cdef Py_ssize_t j, k, n = self._length
|
|
1612
|
+
|
|
1613
|
+
if b is not None:
|
|
1614
|
+
j = n // b
|
|
1615
|
+
return sum([self[k*b:(k+1)*b].add_scalar(-self[k*b]).range_statistic() for k in range(j)]) / j
|
|
1616
|
+
|
|
1617
|
+
cdef double Yn = self._values[n - 1]
|
|
1618
|
+
cdef TimeSeries Z = self.__copy__()
|
|
1619
|
+
for k from 0 <= k < n:
|
|
1620
|
+
Z._values[k] -= (k+1)*Yn / n
|
|
1621
|
+
|
|
1622
|
+
sigma = self.diffs().standard_deviation()
|
|
1623
|
+
|
|
1624
|
+
return (Z.max() - Z.min()) / sigma
|
|
1625
|
+
|
|
1626
|
+
def hurst_exponent(self):
|
|
1627
|
+
r"""
|
|
1628
|
+
Return an estimate of the Hurst exponent of this time series.
|
|
1629
|
+
|
|
1630
|
+
We use the algorithm from pages 61 -- 63 of [Peteres, Fractal
|
|
1631
|
+
Market Analysis (1994); see Google Books].
|
|
1632
|
+
|
|
1633
|
+
We define the Hurst exponent of a constant time series to be 1.
|
|
1634
|
+
|
|
1635
|
+
EXAMPLES:
|
|
1636
|
+
|
|
1637
|
+
The Hurst exponent of Brownian motion is 1/2. We approximate
|
|
1638
|
+
it with some specific samples. Note that the estimator is
|
|
1639
|
+
biased and slightly overestimates. ::
|
|
1640
|
+
|
|
1641
|
+
sage: set_random_seed(0)
|
|
1642
|
+
sage: bm = stats.TimeSeries(10^5).randomize('normal').sums(); bm
|
|
1643
|
+
[0.6767, 0.2756, 0.6332, 0.0469, -0.8897 ...
|
|
1644
|
+
152.2437, 151.5327, 152.7629, 152.9169, 152.9084]
|
|
1645
|
+
sage: bm.hurst_exponent()
|
|
1646
|
+
0.527450972...
|
|
1647
|
+
"""
|
|
1648
|
+
# We use disjoint blocks of size 8, 16, 32, ....
|
|
1649
|
+
cdef Py_ssize_t k = 8
|
|
1650
|
+
if self._length <= 32: # small data, estimate of Hurst will suck but...
|
|
1651
|
+
k = 4
|
|
1652
|
+
v0 = []
|
|
1653
|
+
v1 = []
|
|
1654
|
+
while k <= self._length:
|
|
1655
|
+
try:
|
|
1656
|
+
v1.append(log(self.range_statistic(k)))
|
|
1657
|
+
v0.append(log(k))
|
|
1658
|
+
except ZeroDivisionError: # 0 standard deviation
|
|
1659
|
+
pass
|
|
1660
|
+
k *= 2
|
|
1661
|
+
if not v0:
|
|
1662
|
+
return float(1)
|
|
1663
|
+
if len(v0) == 1:
|
|
1664
|
+
return v1[0]/v0[0]
|
|
1665
|
+
import numpy
|
|
1666
|
+
if int(numpy.version.short_version[0]) > 1:
|
|
1667
|
+
numpy.set_printoptions(legacy="1.25")
|
|
1668
|
+
coeffs = numpy.polyfit(v0,v1,1)
|
|
1669
|
+
return coeffs[0]
|
|
1670
|
+
|
|
1671
|
+
def min(self, bint index=False):
|
|
1672
|
+
r"""
|
|
1673
|
+
Return the smallest value in this time series.
|
|
1674
|
+
|
|
1675
|
+
If this series has length 0, we raise a :exc:`ValueError`.
|
|
1676
|
+
|
|
1677
|
+
INPUT:
|
|
1678
|
+
|
|
1679
|
+
- ``index`` -- boolean (default: ``False``); if ``True``, also return
|
|
1680
|
+
index of minimal entry
|
|
1681
|
+
|
|
1682
|
+
OUTPUT:
|
|
1683
|
+
|
|
1684
|
+
- float; smallest value
|
|
1685
|
+
|
|
1686
|
+
- integer; index of smallest value (only returned if ``index=True``)
|
|
1687
|
+
|
|
1688
|
+
EXAMPLES::
|
|
1689
|
+
|
|
1690
|
+
sage: v = stats.TimeSeries([1,-4,3,-2.5,-4])
|
|
1691
|
+
sage: v.min()
|
|
1692
|
+
-4.0
|
|
1693
|
+
sage: v.min(index=True)
|
|
1694
|
+
(-4.0, 1)
|
|
1695
|
+
"""
|
|
1696
|
+
if self._length == 0:
|
|
1697
|
+
raise ValueError("min() arg is an empty sequence")
|
|
1698
|
+
cdef Py_ssize_t i, j
|
|
1699
|
+
cdef double s = self._values[0]
|
|
1700
|
+
j = 0
|
|
1701
|
+
for i from 1 <= i < self._length:
|
|
1702
|
+
if self._values[i] < s:
|
|
1703
|
+
s = self._values[i]
|
|
1704
|
+
j = i
|
|
1705
|
+
if index:
|
|
1706
|
+
return s, j
|
|
1707
|
+
else:
|
|
1708
|
+
return s
|
|
1709
|
+
|
|
1710
|
+
def max(self, bint index=False):
|
|
1711
|
+
r"""
|
|
1712
|
+
Return the largest value in this time series. If this series
|
|
1713
|
+
has length 0 we raise a :exc:`ValueError`.
|
|
1714
|
+
|
|
1715
|
+
INPUT:
|
|
1716
|
+
|
|
1717
|
+
- ``index`` -- boolean (default: ``False``); if ``True``, also return
|
|
1718
|
+
index of maximum entry
|
|
1719
|
+
|
|
1720
|
+
OUTPUT:
|
|
1721
|
+
|
|
1722
|
+
- float; largest value
|
|
1723
|
+
|
|
1724
|
+
- integer; index of largest value (only returned if ``index=True``)
|
|
1725
|
+
|
|
1726
|
+
EXAMPLES::
|
|
1727
|
+
|
|
1728
|
+
sage: v = stats.TimeSeries([1,-4,3,-2.5,-4,3])
|
|
1729
|
+
sage: v.max()
|
|
1730
|
+
3.0
|
|
1731
|
+
sage: v.max(index=True)
|
|
1732
|
+
(3.0, 2)
|
|
1733
|
+
"""
|
|
1734
|
+
if self._length == 0:
|
|
1735
|
+
raise ValueError("max() arg is an empty sequence")
|
|
1736
|
+
cdef Py_ssize_t i, j = 0
|
|
1737
|
+
cdef double s = self._values[0]
|
|
1738
|
+
for i from 1 <= i < self._length:
|
|
1739
|
+
if self._values[i] > s:
|
|
1740
|
+
s = self._values[i]
|
|
1741
|
+
j = i
|
|
1742
|
+
if index:
|
|
1743
|
+
return s, j
|
|
1744
|
+
else:
|
|
1745
|
+
return s
|
|
1746
|
+
|
|
1747
|
+
def clip_remove(self, min=None, max=None):
|
|
1748
|
+
r"""
|
|
1749
|
+
Return new time series obtained from ``self`` by removing all
|
|
1750
|
+
values that are less than or equal to a certain minimum value
|
|
1751
|
+
or greater than or equal to a certain maximum.
|
|
1752
|
+
|
|
1753
|
+
INPUT:
|
|
1754
|
+
|
|
1755
|
+
- ``min`` -- (default: ``None``) ``None`` or double
|
|
1756
|
+
|
|
1757
|
+
- ``max`` -- (default: ``None``) ``None`` or double
|
|
1758
|
+
|
|
1759
|
+
OUTPUT: a time series
|
|
1760
|
+
|
|
1761
|
+
EXAMPLES::
|
|
1762
|
+
|
|
1763
|
+
sage: v = stats.TimeSeries([1..10])
|
|
1764
|
+
sage: v.clip_remove(3,7)
|
|
1765
|
+
[3.0000, 4.0000, 5.0000, 6.0000, 7.0000]
|
|
1766
|
+
sage: v.clip_remove(3)
|
|
1767
|
+
[3.0000, 4.0000, 5.0000, 6.0000, 7.0000, 8.0000, 9.0000, 10.0000]
|
|
1768
|
+
sage: v.clip_remove(max=7)
|
|
1769
|
+
[1.0000, 2.0000, 3.0000, 4.0000, 5.0000, 6.0000, 7.0000]
|
|
1770
|
+
"""
|
|
1771
|
+
cdef Py_ssize_t i, j
|
|
1772
|
+
cdef TimeSeries t
|
|
1773
|
+
cdef double mn, mx
|
|
1774
|
+
cdef double x
|
|
1775
|
+
if min is None and max is None:
|
|
1776
|
+
return self.copy()
|
|
1777
|
+
# This code is ugly but I think as fast as possible.
|
|
1778
|
+
if min is None and max is not None:
|
|
1779
|
+
# Return everything <= max
|
|
1780
|
+
j = 0
|
|
1781
|
+
mx = max
|
|
1782
|
+
for i from 0 <= i < self._length:
|
|
1783
|
+
if self._values[i] <= mx:
|
|
1784
|
+
j += 1
|
|
1785
|
+
|
|
1786
|
+
t = TimeSeries(j)
|
|
1787
|
+
j = 0
|
|
1788
|
+
for i from 0 <= i < self._length:
|
|
1789
|
+
if self._values[i] <= mx:
|
|
1790
|
+
t._values[j] = self._values[i]
|
|
1791
|
+
j += 1
|
|
1792
|
+
elif max is None and min is not None:
|
|
1793
|
+
# Return everything >= min
|
|
1794
|
+
j = 0
|
|
1795
|
+
mn = min
|
|
1796
|
+
for i from 0 <= i < self._length:
|
|
1797
|
+
if self._values[i] >= mn:
|
|
1798
|
+
j += 1
|
|
1799
|
+
t = TimeSeries(j)
|
|
1800
|
+
j = 0
|
|
1801
|
+
for i from 0 <= i < self._length:
|
|
1802
|
+
if self._values[i] >= mn:
|
|
1803
|
+
t._values[j] = self._values[i]
|
|
1804
|
+
j += 1
|
|
1805
|
+
else:
|
|
1806
|
+
# Return everything between min and max
|
|
1807
|
+
j = 0
|
|
1808
|
+
mn = min
|
|
1809
|
+
mx = max
|
|
1810
|
+
for i from 0 <= i < self._length:
|
|
1811
|
+
x = self._values[i]
|
|
1812
|
+
if x >= mn and x <= mx:
|
|
1813
|
+
j += 1
|
|
1814
|
+
t = TimeSeries(j)
|
|
1815
|
+
j = 0
|
|
1816
|
+
for i from 0 <= i < self._length:
|
|
1817
|
+
x = self._values[i]
|
|
1818
|
+
if x >= mn and x <= mx:
|
|
1819
|
+
t._values[j] = x
|
|
1820
|
+
j += 1
|
|
1821
|
+
return t
|
|
1822
|
+
|
|
1823
|
+
def histogram(self, Py_ssize_t bins=50, bint normalize=False):
|
|
1824
|
+
r"""
|
|
1825
|
+
Return the frequency histogram of the values in
|
|
1826
|
+
this time series divided up into the given
|
|
1827
|
+
number of bins.
|
|
1828
|
+
|
|
1829
|
+
INPUT:
|
|
1830
|
+
|
|
1831
|
+
- ``bins`` -- positive integer (default: 50)
|
|
1832
|
+
|
|
1833
|
+
- ``normalize`` -- boolean (default: ``False``); whether to normalize so the
|
|
1834
|
+
total area in the bars of the histogram is 1
|
|
1835
|
+
|
|
1836
|
+
OUTPUT:
|
|
1837
|
+
|
|
1838
|
+
- counts -- list of counts of numbers of elements in each bin
|
|
1839
|
+
|
|
1840
|
+
- endpoints -- list of 2-tuples (a,b) that give the endpoints of the bins
|
|
1841
|
+
|
|
1842
|
+
EXAMPLES::
|
|
1843
|
+
|
|
1844
|
+
sage: v = stats.TimeSeries([5,4,1.3,2,8,10,3,-5]); v
|
|
1845
|
+
[5.0000, 4.0000, 1.3000, 2.0000, 8.0000, 10.0000, 3.0000, -5.0000]
|
|
1846
|
+
sage: v.histogram(3)
|
|
1847
|
+
([1, 4, 3], [(-5.0, 0.0), (0.0, 5.0), (5.0, 10.0)])
|
|
1848
|
+
"""
|
|
1849
|
+
if bins <= 0:
|
|
1850
|
+
raise ValueError("bins must be positive")
|
|
1851
|
+
|
|
1852
|
+
cdef double mn = self.min(), mx = self.max()
|
|
1853
|
+
cdef double r = mx - mn, step = r/bins
|
|
1854
|
+
cdef Py_ssize_t j
|
|
1855
|
+
|
|
1856
|
+
if r == 0:
|
|
1857
|
+
raise ValueError("bins have 0 width")
|
|
1858
|
+
|
|
1859
|
+
v = [(mn + j*step, mn + (j+1)*step) for j in range(bins)]
|
|
1860
|
+
if self._length == 0:
|
|
1861
|
+
return [], v
|
|
1862
|
+
|
|
1863
|
+
if step == 0:
|
|
1864
|
+
counts = [0]*bins
|
|
1865
|
+
counts[0] = [self._length]
|
|
1866
|
+
return counts, v
|
|
1867
|
+
|
|
1868
|
+
cdef Py_ssize_t i
|
|
1869
|
+
cdef Py_ssize_t* cnts = <Py_ssize_t*>sig_malloc(sizeof(Py_ssize_t)*bins)
|
|
1870
|
+
if cnts == NULL:
|
|
1871
|
+
raise MemoryError
|
|
1872
|
+
for i from 0 <= i < bins:
|
|
1873
|
+
cnts[i] = 0
|
|
1874
|
+
|
|
1875
|
+
for i from 0 <= i < self._length:
|
|
1876
|
+
j = int((self._values[i] - mn)/step)
|
|
1877
|
+
if j >= bins:
|
|
1878
|
+
j = bins-1
|
|
1879
|
+
cnts[j] += 1
|
|
1880
|
+
|
|
1881
|
+
b = 1.0/(self._length * step)
|
|
1882
|
+
if normalize:
|
|
1883
|
+
counts = [cnts[i]*b for i in range(bins)]
|
|
1884
|
+
else:
|
|
1885
|
+
counts = [cnts[i] for i in range(bins)]
|
|
1886
|
+
sig_free(cnts)
|
|
1887
|
+
|
|
1888
|
+
return counts, v
|
|
1889
|
+
|
|
1890
|
+
def plot_histogram(self, bins=50, normalize=True, **kwds):
|
|
1891
|
+
r"""
|
|
1892
|
+
Return histogram plot of this time series with given number of bins.
|
|
1893
|
+
|
|
1894
|
+
INPUT:
|
|
1895
|
+
|
|
1896
|
+
- ``bins`` -- positive integer (default: 50)
|
|
1897
|
+
|
|
1898
|
+
- ``normalize`` -- boolean (default: ``True``); whether to normalize so the
|
|
1899
|
+
total area in the bars of the histogram is 1
|
|
1900
|
+
|
|
1901
|
+
OUTPUT: a histogram plot
|
|
1902
|
+
|
|
1903
|
+
EXAMPLES::
|
|
1904
|
+
|
|
1905
|
+
sage: v = stats.TimeSeries([1..50])
|
|
1906
|
+
sage: v.plot_histogram(bins=10) # needs sage.plot
|
|
1907
|
+
Graphics object consisting of 10 graphics primitives
|
|
1908
|
+
|
|
1909
|
+
::
|
|
1910
|
+
|
|
1911
|
+
sage: v.plot_histogram(bins=3,normalize=False,aspect_ratio=1) # needs sage.plot
|
|
1912
|
+
Graphics object consisting of 3 graphics primitives
|
|
1913
|
+
"""
|
|
1914
|
+
from sage.plot.all import polygon
|
|
1915
|
+
counts, intervals = self.histogram(bins, normalize=normalize)
|
|
1916
|
+
s = 0
|
|
1917
|
+
kwds.setdefault('aspect_ratio','automatic')
|
|
1918
|
+
for i, (x0,x1) in enumerate(intervals):
|
|
1919
|
+
s += polygon([(x0,0), (x0,counts[i]), (x1,counts[i]), (x1,0)], **kwds)
|
|
1920
|
+
if intervals:
|
|
1921
|
+
s.axes_range(ymin=0, ymax=max(counts), xmin=intervals[0][0], xmax=intervals[-1][1])
|
|
1922
|
+
return s
|
|
1923
|
+
|
|
1924
|
+
def plot_candlestick(self, int bins=30):
|
|
1925
|
+
r"""
|
|
1926
|
+
Return a candlestick plot of this time series with the given number
|
|
1927
|
+
of bins.
|
|
1928
|
+
|
|
1929
|
+
A candlestick plot is a style of bar-chart used to view open, high,
|
|
1930
|
+
low, and close stock data. At each bin, the line represents the
|
|
1931
|
+
high / low range. The bar represents the open / close range. The
|
|
1932
|
+
interval is colored blue if the open for that bin is less than the
|
|
1933
|
+
close. If the close is less than the open, then that bin is colored
|
|
1934
|
+
red instead.
|
|
1935
|
+
|
|
1936
|
+
INPUT:
|
|
1937
|
+
|
|
1938
|
+
- ``bins`` -- positive integer (default: 30); the number of bins
|
|
1939
|
+
or candles
|
|
1940
|
+
|
|
1941
|
+
OUTPUT: a candlestick plot
|
|
1942
|
+
|
|
1943
|
+
EXAMPLES:
|
|
1944
|
+
|
|
1945
|
+
Here we look at the candlestick plot for Brownian motion::
|
|
1946
|
+
|
|
1947
|
+
sage: v = stats.TimeSeries(1000).randomize()
|
|
1948
|
+
sage: v.plot_candlestick(bins=20) # needs sage.plot
|
|
1949
|
+
Graphics object consisting of 40 graphics primitives
|
|
1950
|
+
"""
|
|
1951
|
+
from sage.plot.all import line, polygon, Graphics
|
|
1952
|
+
|
|
1953
|
+
cdef TimeSeries t = new_time_series(self._length)
|
|
1954
|
+
cdef TimeSeries s
|
|
1955
|
+
cdef int i, j, n
|
|
1956
|
+
bin_size = int(t._length/bins)
|
|
1957
|
+
rng = t._length - bin_size
|
|
1958
|
+
|
|
1959
|
+
memcpy(t._values, self._values, sizeof(double)*self._length)
|
|
1960
|
+
p = Graphics()
|
|
1961
|
+
|
|
1962
|
+
for i from 0 <= i < bins:
|
|
1963
|
+
n = i*bin_size
|
|
1964
|
+
s = new_time_series(bin_size)
|
|
1965
|
+
for j from 0 <= j < bin_size:
|
|
1966
|
+
s._values[j] = t._values[n + j]
|
|
1967
|
+
low = s.min()
|
|
1968
|
+
high = s.max()
|
|
1969
|
+
open = s._values[0]
|
|
1970
|
+
close = s._values[bin_size-1]
|
|
1971
|
+
left = n + bin_size/3
|
|
1972
|
+
mid = n + bin_size/2
|
|
1973
|
+
right = n + 2*bin_size/3
|
|
1974
|
+
|
|
1975
|
+
rgbcolor = 'blue' if open < close else 'red'
|
|
1976
|
+
|
|
1977
|
+
p += line([(mid, low), (mid, high)], rgbcolor=rgbcolor)
|
|
1978
|
+
p += polygon([(left, open), (right, open), (right, close), (left, close)], rgbcolor=rgbcolor)
|
|
1979
|
+
|
|
1980
|
+
return p
|
|
1981
|
+
|
|
1982
|
+
def numpy(self, copy=True):
|
|
1983
|
+
r"""
|
|
1984
|
+
Return a NumPy version of this time series.
|
|
1985
|
+
|
|
1986
|
+
.. NOTE::
|
|
1987
|
+
|
|
1988
|
+
If copy is ``False``, return a NumPy 1-D array reference to
|
|
1989
|
+
exactly the same block of memory as this time series. This is
|
|
1990
|
+
very, very fast and makes it easy to quickly use all
|
|
1991
|
+
NumPy/SciPy functionality on ``self``. However, it is dangerous
|
|
1992
|
+
because when this time series goes out of scope and is garbage
|
|
1993
|
+
collected, the corresponding NumPy reference object will point
|
|
1994
|
+
to garbage.
|
|
1995
|
+
|
|
1996
|
+
INPUT:
|
|
1997
|
+
|
|
1998
|
+
- ``copy`` -- boolean (default: ``True``)
|
|
1999
|
+
|
|
2000
|
+
OUTPUT: a numpy 1-D array
|
|
2001
|
+
|
|
2002
|
+
EXAMPLES::
|
|
2003
|
+
|
|
2004
|
+
sage: v = stats.TimeSeries([1,-3,4.5,-2])
|
|
2005
|
+
sage: w = v.numpy(copy=False); w
|
|
2006
|
+
array([ 1. , -3. , 4.5, -2. ])
|
|
2007
|
+
sage: type(w)
|
|
2008
|
+
<... 'numpy.ndarray'>
|
|
2009
|
+
sage: w.shape
|
|
2010
|
+
(4,)
|
|
2011
|
+
|
|
2012
|
+
Notice that changing ``w`` also changes ``v`` too! ::
|
|
2013
|
+
|
|
2014
|
+
sage: w[0] = 20
|
|
2015
|
+
sage: w
|
|
2016
|
+
array([20. , -3. , 4.5, -2. ])
|
|
2017
|
+
sage: v
|
|
2018
|
+
[20.0000, -3.0000, 4.5000, -2.0000]
|
|
2019
|
+
|
|
2020
|
+
If you want a separate copy do not give the ``copy=False`` option. ::
|
|
2021
|
+
|
|
2022
|
+
sage: z = v.numpy(); z
|
|
2023
|
+
array([20. , -3. , 4.5, -2. ])
|
|
2024
|
+
sage: z[0] = -10
|
|
2025
|
+
sage: v
|
|
2026
|
+
[20.0000, -3.0000, 4.5000, -2.0000]
|
|
2027
|
+
"""
|
|
2028
|
+
cnumpy.import_array() # This must be called before using the numpy C/api or you will get segfault
|
|
2029
|
+
cdef cnumpy.npy_intp dims[1]
|
|
2030
|
+
dims[0] = self._length
|
|
2031
|
+
cdef cnumpy.ndarray n = cnumpy.PyArray_SimpleNewFromData(1, dims, cnumpy.NPY_DOUBLE, self._values)
|
|
2032
|
+
if copy:
|
|
2033
|
+
return n.copy()
|
|
2034
|
+
else:
|
|
2035
|
+
# Py_INCREF(self)
|
|
2036
|
+
# n.base = self
|
|
2037
|
+
return n
|
|
2038
|
+
|
|
2039
|
+
def randomize(self, distribution='uniform', loc=0, scale=1, **kwds):
|
|
2040
|
+
r"""
|
|
2041
|
+
Randomize the entries in this time series, and return a reference
|
|
2042
|
+
to ``self``. Thus this function both changes ``self`` in place, and
|
|
2043
|
+
returns a copy of ``self``, for convenience.
|
|
2044
|
+
|
|
2045
|
+
INPUT:
|
|
2046
|
+
|
|
2047
|
+
- ``distribution`` -- (default: ``'uniform'``) supported values are:
|
|
2048
|
+
|
|
2049
|
+
- ``'uniform'`` -- from ``loc`` to ``loc + scale``
|
|
2050
|
+
|
|
2051
|
+
- ``'normal'`` -- mean ``loc`` and standard deviation ``scale``
|
|
2052
|
+
|
|
2053
|
+
- ``'semicircle'`` -- with center at ``loc`` (``scale`` is ignored)
|
|
2054
|
+
|
|
2055
|
+
- ``'lognormal'`` -- mean ``loc`` and standard deviation ``scale``
|
|
2056
|
+
|
|
2057
|
+
- ``loc`` -- float (default: 0)
|
|
2058
|
+
|
|
2059
|
+
- ``scale`` -- float (default: 1)
|
|
2060
|
+
|
|
2061
|
+
.. NOTE::
|
|
2062
|
+
|
|
2063
|
+
All random numbers are generated using algorithms that
|
|
2064
|
+
build on the high quality GMP random number function
|
|
2065
|
+
gmp_urandomb_ui. Thus this function fully respects the Sage
|
|
2066
|
+
``set_random_state`` command. It's not quite as fast as the C
|
|
2067
|
+
library random number generator, but is of course much better
|
|
2068
|
+
quality, and is platform independent.
|
|
2069
|
+
|
|
2070
|
+
EXAMPLES:
|
|
2071
|
+
|
|
2072
|
+
We generate 5 uniform random numbers in the interval [0,1]::
|
|
2073
|
+
|
|
2074
|
+
sage: set_random_seed(0)
|
|
2075
|
+
sage: stats.TimeSeries(5).randomize()
|
|
2076
|
+
[0.8685, 0.2816, 0.0229, 0.1456, 0.7314]
|
|
2077
|
+
|
|
2078
|
+
We generate 5 uniform random numbers from 5 to `5+2=7`::
|
|
2079
|
+
|
|
2080
|
+
sage: set_random_seed(0)
|
|
2081
|
+
sage: stats.TimeSeries(10).randomize('uniform', 5, 2)
|
|
2082
|
+
[6.7369, 5.5632, 5.0459, 5.2911, 6.4628, 5.2412, 5.2010, 5.2761, 5.5813, 5.5439]
|
|
2083
|
+
|
|
2084
|
+
We generate 5 normal random values with mean 0 and variance 1. ::
|
|
2085
|
+
|
|
2086
|
+
sage: set_random_seed(0)
|
|
2087
|
+
sage: stats.TimeSeries(5).randomize('normal')
|
|
2088
|
+
[0.6767, -0.4011, 0.3576, -0.5864, -0.9365]
|
|
2089
|
+
|
|
2090
|
+
We generate 10 normal random values with mean 5 and variance 2. ::
|
|
2091
|
+
|
|
2092
|
+
sage: set_random_seed(0)
|
|
2093
|
+
sage: stats.TimeSeries(10).randomize('normal', 5, 2)
|
|
2094
|
+
[6.3534, 4.1978, 5.7153, 3.8273, 3.1269, 2.9598, 3.7484, 6.7472, 3.8986, 4.6271]
|
|
2095
|
+
|
|
2096
|
+
We generate 5 values using the semicircle distribution. ::
|
|
2097
|
+
|
|
2098
|
+
sage: set_random_seed(0)
|
|
2099
|
+
sage: stats.TimeSeries(5).randomize('semicircle')
|
|
2100
|
+
[0.7369, -0.9541, 0.4628, -0.7990, -0.4187]
|
|
2101
|
+
|
|
2102
|
+
We generate 1 million normal random values and create a frequency
|
|
2103
|
+
histogram. ::
|
|
2104
|
+
|
|
2105
|
+
sage: set_random_seed(0)
|
|
2106
|
+
sage: a = stats.TimeSeries(10^6).randomize('normal')
|
|
2107
|
+
sage: a.histogram(10)[0]
|
|
2108
|
+
[36, 1148, 19604, 130699, 340054, 347870, 137953, 21290, 1311, 35]
|
|
2109
|
+
|
|
2110
|
+
We take the above values, and compute the proportion that lie within
|
|
2111
|
+
1, 2, 3, 5, and 6 standard deviations of the mean (0)::
|
|
2112
|
+
|
|
2113
|
+
sage: s = a.standard_deviation()
|
|
2114
|
+
sage: len(a.clip_remove(-s,s))/float(len(a))
|
|
2115
|
+
0.683094
|
|
2116
|
+
sage: len(a.clip_remove(-2*s,2*s))/float(len(a))
|
|
2117
|
+
0.954559
|
|
2118
|
+
sage: len(a.clip_remove(-3*s,3*s))/float(len(a))
|
|
2119
|
+
0.997228
|
|
2120
|
+
sage: len(a.clip_remove(-5*s,5*s))/float(len(a))
|
|
2121
|
+
0.999998
|
|
2122
|
+
|
|
2123
|
+
There were no "six sigma events"::
|
|
2124
|
+
|
|
2125
|
+
sage: len(a.clip_remove(-6*s,6*s))/float(len(a))
|
|
2126
|
+
1.0
|
|
2127
|
+
"""
|
|
2128
|
+
if distribution == 'uniform':
|
|
2129
|
+
self._randomize_uniform(loc, loc + scale)
|
|
2130
|
+
elif distribution == 'normal':
|
|
2131
|
+
self._randomize_normal(loc, scale)
|
|
2132
|
+
elif distribution == 'semicircle':
|
|
2133
|
+
self._randomize_semicircle(loc)
|
|
2134
|
+
elif distribution == 'lognormal':
|
|
2135
|
+
self._randomize_lognormal(loc, scale)
|
|
2136
|
+
else:
|
|
2137
|
+
raise NotImplementedError
|
|
2138
|
+
return self
|
|
2139
|
+
|
|
2140
|
+
def _randomize_uniform(self, double left, double right):
|
|
2141
|
+
r"""
|
|
2142
|
+
Generates a uniform random distribution of doubles between ``left`` and
|
|
2143
|
+
``right`` and stores values in place.
|
|
2144
|
+
|
|
2145
|
+
INPUT:
|
|
2146
|
+
|
|
2147
|
+
- ``left`` -- left bound on random distribution
|
|
2148
|
+
|
|
2149
|
+
- ``right`` -- right bound on random distribution
|
|
2150
|
+
|
|
2151
|
+
EXAMPLES:
|
|
2152
|
+
|
|
2153
|
+
We generate 5 values distributed with respect to the uniform
|
|
2154
|
+
distribution over the interval [0,1]::
|
|
2155
|
+
|
|
2156
|
+
sage: v = stats.TimeSeries(5)
|
|
2157
|
+
sage: set_random_seed(0)
|
|
2158
|
+
sage: v.randomize('uniform')
|
|
2159
|
+
[0.8685, 0.2816, 0.0229, 0.1456, 0.7314]
|
|
2160
|
+
|
|
2161
|
+
We now test that the mean is indeed 0.5::
|
|
2162
|
+
|
|
2163
|
+
sage: v = stats.TimeSeries(10^6)
|
|
2164
|
+
sage: set_random_seed(0)
|
|
2165
|
+
sage: v.randomize('uniform').mean()
|
|
2166
|
+
0.50069085...
|
|
2167
|
+
"""
|
|
2168
|
+
if left >= right:
|
|
2169
|
+
raise ValueError("left must be less than right")
|
|
2170
|
+
|
|
2171
|
+
cdef randstate rstate = current_randstate()
|
|
2172
|
+
cdef Py_ssize_t k
|
|
2173
|
+
cdef double d = right - left
|
|
2174
|
+
for k from 0 <= k < self._length:
|
|
2175
|
+
self._values[k] = rstate.c_rand_double() * d + left
|
|
2176
|
+
|
|
2177
|
+
def _randomize_normal(self, double m, double s):
|
|
2178
|
+
r"""
|
|
2179
|
+
Generates a normal random distribution of doubles with mean ``m`` and
|
|
2180
|
+
standard deviation ``s`` and stores values in place. Uses the
|
|
2181
|
+
Box-Muller algorithm.
|
|
2182
|
+
|
|
2183
|
+
INPUT:
|
|
2184
|
+
|
|
2185
|
+
- ``m`` -- mean
|
|
2186
|
+
|
|
2187
|
+
- ``s`` -- standard deviation
|
|
2188
|
+
|
|
2189
|
+
EXAMPLES:
|
|
2190
|
+
|
|
2191
|
+
We generate 5 values distributed with respect to the normal
|
|
2192
|
+
distribution with mean 0 and standard deviation 1::
|
|
2193
|
+
|
|
2194
|
+
sage: set_random_seed(0)
|
|
2195
|
+
sage: v = stats.TimeSeries(5)
|
|
2196
|
+
sage: v.randomize('normal')
|
|
2197
|
+
[0.6767, -0.4011, 0.3576, -0.5864, -0.9365]
|
|
2198
|
+
|
|
2199
|
+
We now test that the mean is indeed 0::
|
|
2200
|
+
|
|
2201
|
+
sage: set_random_seed(0)
|
|
2202
|
+
sage: v = stats.TimeSeries(10^6)
|
|
2203
|
+
sage: v.randomize('normal').mean()
|
|
2204
|
+
6.2705472723...
|
|
2205
|
+
|
|
2206
|
+
The same test with mean equal to 2 and standard deviation equal
|
|
2207
|
+
to 5::
|
|
2208
|
+
|
|
2209
|
+
sage: set_random_seed(0)
|
|
2210
|
+
sage: v = stats.TimeSeries(10^6)
|
|
2211
|
+
sage: v.randomize('normal', 2, 5).mean()
|
|
2212
|
+
2.0003135273...
|
|
2213
|
+
"""
|
|
2214
|
+
# Ported from http://users.tkk.fi/~nbeijar/soft/terrain/source_o2/boxmuller.c
|
|
2215
|
+
# This the box muller algorithm.
|
|
2216
|
+
cdef randstate rstate = current_randstate()
|
|
2217
|
+
|
|
2218
|
+
cdef double x1, x2, w, y1, y2
|
|
2219
|
+
cdef Py_ssize_t k
|
|
2220
|
+
for k from 0 <= k < self._length:
|
|
2221
|
+
while True:
|
|
2222
|
+
x1 = 2*rstate.c_rand_double() - 1
|
|
2223
|
+
x2 = 2*rstate.c_rand_double() - 1
|
|
2224
|
+
w = x1*x1 + x2*x2
|
|
2225
|
+
if w < 1: break
|
|
2226
|
+
w = sqrt( (-2*log(w))/w )
|
|
2227
|
+
y1 = x1 * w
|
|
2228
|
+
y2 = x2 * w
|
|
2229
|
+
self._values[k] = m + y1*s
|
|
2230
|
+
k += 1
|
|
2231
|
+
if k < self._length:
|
|
2232
|
+
self._values[k] = m + y2*s
|
|
2233
|
+
|
|
2234
|
+
def _randomize_semicircle(self, double center):
|
|
2235
|
+
r"""
|
|
2236
|
+
Generates a semicircle random distribution of doubles about center
|
|
2237
|
+
and stores values in place. Uses the acceptance-rejection method.
|
|
2238
|
+
|
|
2239
|
+
INPUT:
|
|
2240
|
+
|
|
2241
|
+
- ``center`` -- the center of the semicircle distribution
|
|
2242
|
+
|
|
2243
|
+
EXAMPLES:
|
|
2244
|
+
|
|
2245
|
+
We generate 5 values distributed with respect to the semicircle
|
|
2246
|
+
distribution located at center::
|
|
2247
|
+
|
|
2248
|
+
sage: v = stats.TimeSeries(5)
|
|
2249
|
+
sage: set_random_seed(0)
|
|
2250
|
+
sage: v.randomize('semicircle')
|
|
2251
|
+
[0.7369, -0.9541, 0.4628, -0.7990, -0.4187]
|
|
2252
|
+
|
|
2253
|
+
We now test that the mean is indeed the center::
|
|
2254
|
+
|
|
2255
|
+
sage: v = stats.TimeSeries(10^6)
|
|
2256
|
+
sage: set_random_seed(0)
|
|
2257
|
+
sage: v.randomize('semicircle').mean()
|
|
2258
|
+
0.0007207497...
|
|
2259
|
+
|
|
2260
|
+
The same test with center equal to 2::
|
|
2261
|
+
|
|
2262
|
+
sage: v = stats.TimeSeries(10^6)
|
|
2263
|
+
sage: set_random_seed(0)
|
|
2264
|
+
sage: v.randomize('semicircle', 2).mean()
|
|
2265
|
+
2.0007207497...
|
|
2266
|
+
"""
|
|
2267
|
+
cdef Py_ssize_t k
|
|
2268
|
+
cdef double x, y, s, d = 2, left = center - 1, z
|
|
2269
|
+
cdef randstate rstate = current_randstate()
|
|
2270
|
+
z = d*d
|
|
2271
|
+
s = 1.5707963267948966192 # pi/2
|
|
2272
|
+
for k from 0 <= k < self._length:
|
|
2273
|
+
while True:
|
|
2274
|
+
x = rstate.c_rand_double() * d - 1
|
|
2275
|
+
y = rstate.c_rand_double() * s
|
|
2276
|
+
if y*y + x*x < 1:
|
|
2277
|
+
break
|
|
2278
|
+
self._values[k] = x + center
|
|
2279
|
+
|
|
2280
|
+
def _randomize_lognormal(self, double m, double s):
|
|
2281
|
+
r"""
|
|
2282
|
+
Generates a log-normal random distribution of doubles with mean ``m``
|
|
2283
|
+
and standard deviation ``s``. Uses Box-Muller algorithm and the
|
|
2284
|
+
identity: if `Y` is a random variable with normal distribution then
|
|
2285
|
+
`X = \exp(Y)` is a random variable with log-normal distribution.
|
|
2286
|
+
|
|
2287
|
+
INPUT:
|
|
2288
|
+
|
|
2289
|
+
- ``m`` -- mean
|
|
2290
|
+
|
|
2291
|
+
- ``s`` -- standard deviation
|
|
2292
|
+
|
|
2293
|
+
EXAMPLES:
|
|
2294
|
+
|
|
2295
|
+
We generate 5 values distributed with respect to the lognormal
|
|
2296
|
+
distribution with mean 0 and standard deviation 1::
|
|
2297
|
+
|
|
2298
|
+
sage: set_random_seed(0)
|
|
2299
|
+
sage: v = stats.TimeSeries(5)
|
|
2300
|
+
sage: v.randomize('lognormal')
|
|
2301
|
+
[1.9674, 0.6696, 1.4299, 0.5563, 0.3920]
|
|
2302
|
+
|
|
2303
|
+
We now test that the mean is indeed `\sqrt{e}`::
|
|
2304
|
+
|
|
2305
|
+
sage: set_random_seed(0)
|
|
2306
|
+
sage: v = stats.TimeSeries(10^6)
|
|
2307
|
+
sage: v.randomize('lognormal').mean()
|
|
2308
|
+
1.647351973...
|
|
2309
|
+
sage: exp(0.5) # needs sage.symbolic
|
|
2310
|
+
1.648721270...
|
|
2311
|
+
|
|
2312
|
+
A log-normal distribution can be simply thought of as the logarithm
|
|
2313
|
+
of a normally distributed data set. We test that here by generating
|
|
2314
|
+
5 values distributed with respect to the normal distribution with mean
|
|
2315
|
+
0 and standard deviation 1::
|
|
2316
|
+
|
|
2317
|
+
sage: set_random_seed(0)
|
|
2318
|
+
sage: w = stats.TimeSeries(5)
|
|
2319
|
+
sage: w.randomize('normal')
|
|
2320
|
+
[0.6767, -0.4011, 0.3576, -0.5864, -0.9365]
|
|
2321
|
+
sage: exp(w)
|
|
2322
|
+
[1.9674, 0.6696, 1.4299, 0.5563, 0.3920]
|
|
2323
|
+
"""
|
|
2324
|
+
# Ported from http://users.tkk.fi/~nbeijar/soft/terrain/source_o2/boxmuller.c
|
|
2325
|
+
# This the box muller algorithm.
|
|
2326
|
+
cdef randstate rstate = current_randstate()
|
|
2327
|
+
cdef double x1, x2, w, y1, y2
|
|
2328
|
+
cdef Py_ssize_t k
|
|
2329
|
+
for k from 0 <= k < self._length:
|
|
2330
|
+
while True:
|
|
2331
|
+
x1 = 2*rstate.c_rand_double() - 1
|
|
2332
|
+
x2 = 2*rstate.c_rand_double() - 1
|
|
2333
|
+
w = x1*x1 + x2*x2
|
|
2334
|
+
if w < 1: break
|
|
2335
|
+
w = sqrt( (-2*log(w))/w )
|
|
2336
|
+
y1 = x1 * w
|
|
2337
|
+
y2 = x2 * w
|
|
2338
|
+
self._values[k] = exp(m + y1*s)
|
|
2339
|
+
k += 1
|
|
2340
|
+
if k < self._length:
|
|
2341
|
+
self._values[k] = exp(m + y2*s)
|
|
2342
|
+
|
|
2343
|
+
def fft(self, bint overwrite=False):
|
|
2344
|
+
r"""
|
|
2345
|
+
Return the real discrete fast Fourier transform of ``self``, as a
|
|
2346
|
+
real time series:
|
|
2347
|
+
|
|
2348
|
+
.. MATH::
|
|
2349
|
+
|
|
2350
|
+
[y(0),\Re(y(1)),\Im(y(1)),\dots,\Re(y(n/2))] \text{ if $n$ is even}
|
|
2351
|
+
|
|
2352
|
+
[y(0),\Re(y(1)),\Im(y(1)),\dots,\Re(y(n/2)),\Im(y(n/2))] \text{ if $n$ is odd}
|
|
2353
|
+
|
|
2354
|
+
where
|
|
2355
|
+
|
|
2356
|
+
.. MATH::
|
|
2357
|
+
|
|
2358
|
+
y(j) = \sum_{k=0}^{n-1} x[k] \cdot \exp(-\sqrt{-1} \cdot jk \cdot 2\pi/n)
|
|
2359
|
+
|
|
2360
|
+
for `j = 0,\dots,n-1`. Note that `y(-j) = y(n-j)`.
|
|
2361
|
+
|
|
2362
|
+
EXAMPLES::
|
|
2363
|
+
|
|
2364
|
+
sage: v = stats.TimeSeries([1..9]); v
|
|
2365
|
+
[1.0000, 2.0000, 3.0000, 4.0000, 5.0000, 6.0000, 7.0000, 8.0000, 9.0000]
|
|
2366
|
+
sage: w = v.fft(); w # needs scipy
|
|
2367
|
+
[45.0000, -4.5000, 12.3636, -4.5000, 5.3629, -4.5000, 2.5981, -4.5000, 0.7935]
|
|
2368
|
+
|
|
2369
|
+
We get just the series of real parts of ::
|
|
2370
|
+
|
|
2371
|
+
sage: stats.TimeSeries([w[0]]) + w[1:].scale_time(2) # needs scipy
|
|
2372
|
+
[45.0000, -4.5000, -4.5000, -4.5000, -4.5000]
|
|
2373
|
+
|
|
2374
|
+
An example with an even number of terms::
|
|
2375
|
+
|
|
2376
|
+
sage: v = stats.TimeSeries([1..10]); v
|
|
2377
|
+
[1.0000, 2.0000, 3.0000, 4.0000, 5.0000, 6.0000, 7.0000, 8.0000, 9.0000, 10.0000]
|
|
2378
|
+
sage: w = v.fft(); w # needs scipy
|
|
2379
|
+
[55.0000, -5.0000, 15.3884, -5.0000, 6.8819, -5.0000, 3.6327, -5.0000, 1.6246, -5.0000]
|
|
2380
|
+
sage: v.fft().ifft() # needs scipy
|
|
2381
|
+
[1.0000, 2.0000, 3.0000, 4.0000, 5.0000, 6.0000, 7.0000, 8.0000, 9.0000, 10.0000]
|
|
2382
|
+
"""
|
|
2383
|
+
import scipy.fftpack
|
|
2384
|
+
if overwrite:
|
|
2385
|
+
y = self
|
|
2386
|
+
else:
|
|
2387
|
+
y = self.__copy__()
|
|
2388
|
+
w = y.numpy(copy=False)
|
|
2389
|
+
scipy.fftpack.rfft(w, overwrite_x=1)
|
|
2390
|
+
return y
|
|
2391
|
+
|
|
2392
|
+
def ifft(self, bint overwrite=False):
|
|
2393
|
+
r"""
|
|
2394
|
+
Return the real discrete inverse fast Fourier transform of
|
|
2395
|
+
``self``, which is also a real time series.
|
|
2396
|
+
|
|
2397
|
+
This is the inverse of ``fft()``.
|
|
2398
|
+
|
|
2399
|
+
The returned real array contains
|
|
2400
|
+
|
|
2401
|
+
.. MATH::
|
|
2402
|
+
|
|
2403
|
+
[y(0),y(1),\dots,y(n-1)]
|
|
2404
|
+
|
|
2405
|
+
where for `n` is even
|
|
2406
|
+
|
|
2407
|
+
.. MATH::
|
|
2408
|
+
|
|
2409
|
+
y(j)
|
|
2410
|
+
=
|
|
2411
|
+
1/n \left(
|
|
2412
|
+
\sum_{k=1}^{n/2-1}
|
|
2413
|
+
(x[2k-1]+\sqrt{-1} \cdot x[2k])
|
|
2414
|
+
\cdot \exp(\sqrt{-1} \cdot jk \cdot 2pi/n)
|
|
2415
|
+
+ c.c. + x[0] + (-1)^j x[n-1]
|
|
2416
|
+
\right)
|
|
2417
|
+
|
|
2418
|
+
and for `n` is odd
|
|
2419
|
+
|
|
2420
|
+
.. MATH::
|
|
2421
|
+
|
|
2422
|
+
y(j)
|
|
2423
|
+
=
|
|
2424
|
+
1/n \left(
|
|
2425
|
+
\sum_{k=1}^{(n-1)/2}
|
|
2426
|
+
(x[2k-1]+\sqrt{-1} \cdot x[2k])
|
|
2427
|
+
\cdot \exp(\sqrt{-1} \cdot jk \cdot 2pi/n)
|
|
2428
|
+
+ c.c. + x[0]
|
|
2429
|
+
\right)
|
|
2430
|
+
|
|
2431
|
+
where `c.c.` denotes complex conjugate of preceding expression.
|
|
2432
|
+
|
|
2433
|
+
EXAMPLES::
|
|
2434
|
+
|
|
2435
|
+
sage: v = stats.TimeSeries([1..10]); v
|
|
2436
|
+
[1.0000, 2.0000, 3.0000, 4.0000, 5.0000, 6.0000, 7.0000, 8.0000, 9.0000, 10.0000]
|
|
2437
|
+
sage: v.ifft() # needs scipy
|
|
2438
|
+
[5.1000, -5.6876, 1.4764, -1.0774, 0.4249, -0.1000, -0.2249, 0.6663, -1.2764, 1.6988]
|
|
2439
|
+
sage: v.ifft().fft() # needs scipy
|
|
2440
|
+
[1.0000, 2.0000, 3.0000, 4.0000, 5.0000, 6.0000, 7.0000, 8.0000, 9.0000, 10.0000]
|
|
2441
|
+
"""
|
|
2442
|
+
import scipy.fftpack
|
|
2443
|
+
if overwrite:
|
|
2444
|
+
y = self
|
|
2445
|
+
else:
|
|
2446
|
+
y = self.__copy__()
|
|
2447
|
+
w = y.numpy(copy=False)
|
|
2448
|
+
scipy.fftpack.irfft(w, overwrite_x=1)
|
|
2449
|
+
return y
|
|
2450
|
+
|
|
2451
|
+
|
|
2452
|
+
cdef new_time_series(Py_ssize_t length):
|
|
2453
|
+
r"""
|
|
2454
|
+
Return a new uninitialized time series of the given length.
|
|
2455
|
+
The entries of the time series are garbage.
|
|
2456
|
+
|
|
2457
|
+
INPUT:
|
|
2458
|
+
|
|
2459
|
+
- ``length`` -- integer
|
|
2460
|
+
|
|
2461
|
+
OUTPUT: a time series
|
|
2462
|
+
|
|
2463
|
+
EXAMPLES:
|
|
2464
|
+
|
|
2465
|
+
This uses ``new_time_series`` implicitly::
|
|
2466
|
+
|
|
2467
|
+
sage: v = stats.TimeSeries([1,-3,4.5,-2])
|
|
2468
|
+
sage: v.__copy__()
|
|
2469
|
+
[1.0000, -3.0000, 4.5000, -2.0000]
|
|
2470
|
+
"""
|
|
2471
|
+
if length < 0:
|
|
2472
|
+
raise ValueError("length must be nonnegative")
|
|
2473
|
+
cdef TimeSeries t = TimeSeries.__new__(TimeSeries)
|
|
2474
|
+
t._length = length
|
|
2475
|
+
t._values = <double*> sig_malloc(sizeof(double)*length)
|
|
2476
|
+
return t
|
|
2477
|
+
|
|
2478
|
+
|
|
2479
|
+
@cython.binding(True)
|
|
2480
|
+
def unpickle_time_series_v1(bytes v, Py_ssize_t n):
|
|
2481
|
+
r"""
|
|
2482
|
+
Version 1 unpickle method.
|
|
2483
|
+
|
|
2484
|
+
INPUT:
|
|
2485
|
+
|
|
2486
|
+
- ``v`` -- a raw char buffer
|
|
2487
|
+
|
|
2488
|
+
EXAMPLES::
|
|
2489
|
+
|
|
2490
|
+
sage: v = stats.TimeSeries([1,2,3])
|
|
2491
|
+
sage: s = v.__reduce__()[1][0]
|
|
2492
|
+
sage: type(s)
|
|
2493
|
+
<class 'bytes'>
|
|
2494
|
+
sage: sage.stats.time_series.unpickle_time_series_v1(s,3)
|
|
2495
|
+
[1.0000, 2.0000, 3.0000]
|
|
2496
|
+
sage: sage.stats.time_series.unpickle_time_series_v1(s+s,6)
|
|
2497
|
+
[1.0000, 2.0000, 3.0000, 1.0000, 2.0000, 3.0000]
|
|
2498
|
+
sage: sage.stats.time_series.unpickle_time_series_v1(b'',0)
|
|
2499
|
+
[]
|
|
2500
|
+
"""
|
|
2501
|
+
cdef TimeSeries t = new_time_series(n)
|
|
2502
|
+
memcpy(t._values, PyBytes_AsString(v), n * sizeof(double))
|
|
2503
|
+
return t
|
|
2504
|
+
|
|
2505
|
+
|
|
2506
|
+
register_unpickle_override('sage.finance.time_series', 'unpickle_time_series_v1', unpickle_time_series_v1)
|
|
2507
|
+
|
|
2508
|
+
|
|
2509
|
+
def autoregressive_fit(acvs):
|
|
2510
|
+
r"""
|
|
2511
|
+
Given a sequence of lagged autocovariances of length `M` produce
|
|
2512
|
+
`a_1,\dots,a_p` so that the first `M` autocovariance coefficients
|
|
2513
|
+
of the autoregressive processes `X_t=a_1X_{t_1}+\cdots+a_pX_{t-p}+Z_t`
|
|
2514
|
+
are the same as the input sequence.
|
|
2515
|
+
|
|
2516
|
+
The function works by solving the Yule-Walker equations
|
|
2517
|
+
`\Gamma a =\gamma`, where `\gamma=(\gamma(1),\dots,\gamma(M))`,
|
|
2518
|
+
`a=(a_1,\dots,a_M)`, with `\gamma(i)` the autocovariance of lag `i`
|
|
2519
|
+
and `\Gamma_{ij}=\gamma(i-j)`.
|
|
2520
|
+
"""
|
|
2521
|
+
cdef TimeSeries c
|
|
2522
|
+
cdef Py_ssize_t i
|
|
2523
|
+
|
|
2524
|
+
M = len(acvs)-1
|
|
2525
|
+
|
|
2526
|
+
if M <= 0:
|
|
2527
|
+
raise ValueError("M must be positive")
|
|
2528
|
+
|
|
2529
|
+
if not isinstance(acvs, TimeSeries):
|
|
2530
|
+
c = TimeSeries(acvs)
|
|
2531
|
+
else:
|
|
2532
|
+
c = acvs
|
|
2533
|
+
|
|
2534
|
+
# Also create the numpy vector v with entries c(1), ..., c(M).
|
|
2535
|
+
v = c[1:].numpy()
|
|
2536
|
+
|
|
2537
|
+
# 2. Create the autocovariances numpy 2d array A whose i,j entry
|
|
2538
|
+
# is c(|i-j|).
|
|
2539
|
+
import numpy
|
|
2540
|
+
A = numpy.array([[c[abs(j-k)] for j in range(M)] for k in range(M)])
|
|
2541
|
+
|
|
2542
|
+
# 3. Solve the equation A * x = v
|
|
2543
|
+
x = numpy.linalg.solve(A, v)
|
|
2544
|
+
|
|
2545
|
+
# 4. The entries of x give the linear filter coefficients.
|
|
2546
|
+
return TimeSeries(x)
|