passagemath-modules 10.6.31rc3__cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_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.

Files changed (807) hide show
  1. passagemath_modules-10.6.31rc3.dist-info/METADATA +281 -0
  2. passagemath_modules-10.6.31rc3.dist-info/RECORD +807 -0
  3. passagemath_modules-10.6.31rc3.dist-info/WHEEL +6 -0
  4. passagemath_modules-10.6.31rc3.dist-info/top_level.txt +2 -0
  5. passagemath_modules.libs/libgfortran-83c28eba.so.5.0.0 +0 -0
  6. passagemath_modules.libs/libgmp-6e109695.so.10.5.0 +0 -0
  7. passagemath_modules.libs/libgsl-cda90e79.so.28.0.0 +0 -0
  8. passagemath_modules.libs/libmpc-7f678fcf.so.3.3.1 +0 -0
  9. passagemath_modules.libs/libmpfr-82690d50.so.6.2.1 +0 -0
  10. passagemath_modules.libs/libopenblasp-r0-6dcb67f9.3.29.so +0 -0
  11. passagemath_modules.libs/libquadmath-2284e583.so.0.0.0 +0 -0
  12. sage/algebras/all__sagemath_modules.py +20 -0
  13. sage/algebras/catalog.py +148 -0
  14. sage/algebras/clifford_algebra.py +3107 -0
  15. sage/algebras/clifford_algebra_element.cpython-314-x86_64-linux-gnu.so +0 -0
  16. sage/algebras/clifford_algebra_element.pxd +16 -0
  17. sage/algebras/clifford_algebra_element.pyx +997 -0
  18. sage/algebras/commutative_dga.py +4252 -0
  19. sage/algebras/exterior_algebra_groebner.cpython-314-x86_64-linux-gnu.so +0 -0
  20. sage/algebras/exterior_algebra_groebner.pxd +55 -0
  21. sage/algebras/exterior_algebra_groebner.pyx +727 -0
  22. sage/algebras/finite_dimensional_algebras/all.py +2 -0
  23. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py +1029 -0
  24. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.cpython-314-x86_64-linux-gnu.so +0 -0
  25. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pxd +12 -0
  26. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx +706 -0
  27. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_ideal.py +196 -0
  28. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py +255 -0
  29. sage/algebras/finite_gca.py +528 -0
  30. sage/algebras/group_algebra.py +232 -0
  31. sage/algebras/lie_algebras/abelian.py +197 -0
  32. sage/algebras/lie_algebras/affine_lie_algebra.py +1213 -0
  33. sage/algebras/lie_algebras/all.py +25 -0
  34. sage/algebras/lie_algebras/all__sagemath_modules.py +1 -0
  35. sage/algebras/lie_algebras/bch.py +177 -0
  36. sage/algebras/lie_algebras/bgg_dual_module.py +1184 -0
  37. sage/algebras/lie_algebras/bgg_resolution.py +232 -0
  38. sage/algebras/lie_algebras/center_uea.py +767 -0
  39. sage/algebras/lie_algebras/classical_lie_algebra.py +2516 -0
  40. sage/algebras/lie_algebras/examples.py +683 -0
  41. sage/algebras/lie_algebras/free_lie_algebra.py +973 -0
  42. sage/algebras/lie_algebras/heisenberg.py +820 -0
  43. sage/algebras/lie_algebras/lie_algebra.py +1562 -0
  44. sage/algebras/lie_algebras/lie_algebra_element.cpython-314-x86_64-linux-gnu.so +0 -0
  45. sage/algebras/lie_algebras/lie_algebra_element.pxd +68 -0
  46. sage/algebras/lie_algebras/lie_algebra_element.pyx +2122 -0
  47. sage/algebras/lie_algebras/morphism.py +661 -0
  48. sage/algebras/lie_algebras/nilpotent_lie_algebra.py +457 -0
  49. sage/algebras/lie_algebras/onsager.py +1324 -0
  50. sage/algebras/lie_algebras/poincare_birkhoff_witt.py +816 -0
  51. sage/algebras/lie_algebras/quotient.py +462 -0
  52. sage/algebras/lie_algebras/rank_two_heisenberg_virasoro.py +355 -0
  53. sage/algebras/lie_algebras/representation.py +1040 -0
  54. sage/algebras/lie_algebras/structure_coefficients.py +459 -0
  55. sage/algebras/lie_algebras/subalgebra.py +967 -0
  56. sage/algebras/lie_algebras/symplectic_derivation.py +289 -0
  57. sage/algebras/lie_algebras/verma_module.py +1630 -0
  58. sage/algebras/lie_algebras/virasoro.py +1186 -0
  59. sage/algebras/octonion_algebra.cpython-314-x86_64-linux-gnu.so +0 -0
  60. sage/algebras/octonion_algebra.pxd +20 -0
  61. sage/algebras/octonion_algebra.pyx +987 -0
  62. sage/algebras/orlik_solomon.py +907 -0
  63. sage/algebras/orlik_terao.py +779 -0
  64. sage/algebras/steenrod/all.py +7 -0
  65. sage/algebras/steenrod/steenrod_algebra.py +4258 -0
  66. sage/algebras/steenrod/steenrod_algebra_bases.py +1179 -0
  67. sage/algebras/steenrod/steenrod_algebra_misc.py +1167 -0
  68. sage/algebras/steenrod/steenrod_algebra_mult.py +954 -0
  69. sage/algebras/weyl_algebra.py +1126 -0
  70. sage/all__sagemath_modules.py +62 -0
  71. sage/calculus/all__sagemath_modules.py +19 -0
  72. sage/calculus/expr.py +205 -0
  73. sage/calculus/integration.cpython-314-x86_64-linux-gnu.so +0 -0
  74. sage/calculus/integration.pyx +698 -0
  75. sage/calculus/interpolation.cpython-314-x86_64-linux-gnu.so +0 -0
  76. sage/calculus/interpolation.pxd +13 -0
  77. sage/calculus/interpolation.pyx +387 -0
  78. sage/calculus/interpolators.cpython-314-x86_64-linux-gnu.so +0 -0
  79. sage/calculus/interpolators.pyx +326 -0
  80. sage/calculus/ode.cpython-314-x86_64-linux-gnu.so +0 -0
  81. sage/calculus/ode.pxd +5 -0
  82. sage/calculus/ode.pyx +610 -0
  83. sage/calculus/riemann.cpython-314-x86_64-linux-gnu.so +0 -0
  84. sage/calculus/riemann.pyx +1521 -0
  85. sage/calculus/test_sympy.py +201 -0
  86. sage/calculus/transforms/all.py +7 -0
  87. sage/calculus/transforms/dft.py +844 -0
  88. sage/calculus/transforms/dwt.cpython-314-x86_64-linux-gnu.so +0 -0
  89. sage/calculus/transforms/dwt.pxd +7 -0
  90. sage/calculus/transforms/dwt.pyx +160 -0
  91. sage/calculus/transforms/fft.cpython-314-x86_64-linux-gnu.so +0 -0
  92. sage/calculus/transforms/fft.pxd +12 -0
  93. sage/calculus/transforms/fft.pyx +487 -0
  94. sage/calculus/wester.py +662 -0
  95. sage/coding/abstract_code.py +1108 -0
  96. sage/coding/ag_code.py +868 -0
  97. sage/coding/ag_code_decoders.cpython-314-x86_64-linux-gnu.so +0 -0
  98. sage/coding/ag_code_decoders.pyx +2639 -0
  99. sage/coding/all.py +15 -0
  100. sage/coding/bch_code.py +494 -0
  101. sage/coding/binary_code.cpython-314-x86_64-linux-gnu.so +0 -0
  102. sage/coding/binary_code.pxd +124 -0
  103. sage/coding/binary_code.pyx +4139 -0
  104. sage/coding/bounds_catalog.py +43 -0
  105. sage/coding/channel.py +819 -0
  106. sage/coding/channels_catalog.py +29 -0
  107. sage/coding/code_bounds.py +755 -0
  108. sage/coding/code_constructions.py +804 -0
  109. sage/coding/codes_catalog.py +111 -0
  110. sage/coding/cyclic_code.py +1329 -0
  111. sage/coding/databases.py +316 -0
  112. sage/coding/decoder.py +373 -0
  113. sage/coding/decoders_catalog.py +88 -0
  114. sage/coding/delsarte_bounds.py +709 -0
  115. sage/coding/encoder.py +390 -0
  116. sage/coding/encoders_catalog.py +64 -0
  117. sage/coding/extended_code.py +468 -0
  118. sage/coding/gabidulin_code.py +1058 -0
  119. sage/coding/golay_code.py +404 -0
  120. sage/coding/goppa_code.py +441 -0
  121. sage/coding/grs_code.py +2371 -0
  122. sage/coding/guava.py +107 -0
  123. sage/coding/guruswami_sudan/all.py +1 -0
  124. sage/coding/guruswami_sudan/gs_decoder.py +897 -0
  125. sage/coding/guruswami_sudan/interpolation.py +409 -0
  126. sage/coding/guruswami_sudan/utils.py +176 -0
  127. sage/coding/hamming_code.py +176 -0
  128. sage/coding/information_set_decoder.py +1032 -0
  129. sage/coding/kasami_codes.cpython-314-x86_64-linux-gnu.so +0 -0
  130. sage/coding/kasami_codes.pyx +351 -0
  131. sage/coding/linear_code.py +3067 -0
  132. sage/coding/linear_code_no_metric.py +1354 -0
  133. sage/coding/linear_rank_metric.py +961 -0
  134. sage/coding/parity_check_code.py +353 -0
  135. sage/coding/punctured_code.py +719 -0
  136. sage/coding/reed_muller_code.py +999 -0
  137. sage/coding/self_dual_codes.py +942 -0
  138. sage/coding/source_coding/all.py +2 -0
  139. sage/coding/source_coding/huffman.py +553 -0
  140. sage/coding/subfield_subcode.py +423 -0
  141. sage/coding/two_weight_db.py +399 -0
  142. sage/combinat/all__sagemath_modules.py +7 -0
  143. sage/combinat/cartesian_product.py +347 -0
  144. sage/combinat/family.py +11 -0
  145. sage/combinat/free_module.py +1977 -0
  146. sage/combinat/root_system/all.py +147 -0
  147. sage/combinat/root_system/ambient_space.py +527 -0
  148. sage/combinat/root_system/associahedron.py +471 -0
  149. sage/combinat/root_system/braid_move_calculator.py +143 -0
  150. sage/combinat/root_system/braid_orbit.cpython-314-x86_64-linux-gnu.so +0 -0
  151. sage/combinat/root_system/braid_orbit.pyx +144 -0
  152. sage/combinat/root_system/branching_rules.py +2301 -0
  153. sage/combinat/root_system/cartan_matrix.py +1245 -0
  154. sage/combinat/root_system/cartan_type.py +3069 -0
  155. sage/combinat/root_system/coxeter_group.py +162 -0
  156. sage/combinat/root_system/coxeter_matrix.py +1261 -0
  157. sage/combinat/root_system/coxeter_type.py +681 -0
  158. sage/combinat/root_system/dynkin_diagram.py +900 -0
  159. sage/combinat/root_system/extended_affine_weyl_group.py +2993 -0
  160. sage/combinat/root_system/fundamental_group.py +795 -0
  161. sage/combinat/root_system/hecke_algebra_representation.py +1203 -0
  162. sage/combinat/root_system/integrable_representations.py +1227 -0
  163. sage/combinat/root_system/non_symmetric_macdonald_polynomials.py +1965 -0
  164. sage/combinat/root_system/pieri_factors.py +1147 -0
  165. sage/combinat/root_system/plot.py +1615 -0
  166. sage/combinat/root_system/root_lattice_realization_algebras.py +1214 -0
  167. sage/combinat/root_system/root_lattice_realizations.py +4628 -0
  168. sage/combinat/root_system/root_space.py +487 -0
  169. sage/combinat/root_system/root_system.py +882 -0
  170. sage/combinat/root_system/type_A.py +348 -0
  171. sage/combinat/root_system/type_A_affine.py +227 -0
  172. sage/combinat/root_system/type_A_infinity.py +241 -0
  173. sage/combinat/root_system/type_B.py +347 -0
  174. sage/combinat/root_system/type_BC_affine.py +287 -0
  175. sage/combinat/root_system/type_B_affine.py +216 -0
  176. sage/combinat/root_system/type_C.py +317 -0
  177. sage/combinat/root_system/type_C_affine.py +188 -0
  178. sage/combinat/root_system/type_D.py +357 -0
  179. sage/combinat/root_system/type_D_affine.py +208 -0
  180. sage/combinat/root_system/type_E.py +641 -0
  181. sage/combinat/root_system/type_E_affine.py +231 -0
  182. sage/combinat/root_system/type_F.py +387 -0
  183. sage/combinat/root_system/type_F_affine.py +137 -0
  184. sage/combinat/root_system/type_G.py +293 -0
  185. sage/combinat/root_system/type_G_affine.py +132 -0
  186. sage/combinat/root_system/type_H.py +105 -0
  187. sage/combinat/root_system/type_I.py +110 -0
  188. sage/combinat/root_system/type_Q.py +150 -0
  189. sage/combinat/root_system/type_affine.py +509 -0
  190. sage/combinat/root_system/type_dual.py +704 -0
  191. sage/combinat/root_system/type_folded.py +301 -0
  192. sage/combinat/root_system/type_marked.py +748 -0
  193. sage/combinat/root_system/type_reducible.py +601 -0
  194. sage/combinat/root_system/type_relabel.py +730 -0
  195. sage/combinat/root_system/type_super_A.py +837 -0
  196. sage/combinat/root_system/weight_lattice_realizations.py +1188 -0
  197. sage/combinat/root_system/weight_space.py +639 -0
  198. sage/combinat/root_system/weyl_characters.py +2238 -0
  199. sage/crypto/__init__.py +4 -0
  200. sage/crypto/all.py +28 -0
  201. sage/crypto/block_cipher/all.py +7 -0
  202. sage/crypto/block_cipher/des.py +1065 -0
  203. sage/crypto/block_cipher/miniaes.py +2171 -0
  204. sage/crypto/block_cipher/present.py +909 -0
  205. sage/crypto/block_cipher/sdes.py +1527 -0
  206. sage/crypto/boolean_function.cpython-314-x86_64-linux-gnu.so +0 -0
  207. sage/crypto/boolean_function.pxd +10 -0
  208. sage/crypto/boolean_function.pyx +1487 -0
  209. sage/crypto/cipher.py +78 -0
  210. sage/crypto/classical.py +3668 -0
  211. sage/crypto/classical_cipher.py +569 -0
  212. sage/crypto/cryptosystem.py +387 -0
  213. sage/crypto/key_exchange/all.py +7 -0
  214. sage/crypto/key_exchange/catalog.py +24 -0
  215. sage/crypto/key_exchange/diffie_hellman.py +323 -0
  216. sage/crypto/key_exchange/key_exchange_scheme.py +107 -0
  217. sage/crypto/lattice.py +312 -0
  218. sage/crypto/lfsr.py +295 -0
  219. sage/crypto/lwe.py +840 -0
  220. sage/crypto/mq/__init__.py +4 -0
  221. sage/crypto/mq/mpolynomialsystemgenerator.py +204 -0
  222. sage/crypto/mq/rijndael_gf.py +2345 -0
  223. sage/crypto/mq/sbox.py +7 -0
  224. sage/crypto/mq/sr.py +3344 -0
  225. sage/crypto/public_key/all.py +5 -0
  226. sage/crypto/public_key/blum_goldwasser.py +776 -0
  227. sage/crypto/sbox.cpython-314-x86_64-linux-gnu.so +0 -0
  228. sage/crypto/sbox.pyx +2090 -0
  229. sage/crypto/sboxes.py +2090 -0
  230. sage/crypto/stream.py +390 -0
  231. sage/crypto/stream_cipher.py +297 -0
  232. sage/crypto/util.py +519 -0
  233. sage/ext/all__sagemath_modules.py +1 -0
  234. sage/ext/interpreters/__init__.py +1 -0
  235. sage/ext/interpreters/all__sagemath_modules.py +2 -0
  236. sage/ext/interpreters/wrapper_cc.cpython-314-x86_64-linux-gnu.so +0 -0
  237. sage/ext/interpreters/wrapper_cc.pxd +30 -0
  238. sage/ext/interpreters/wrapper_cc.pyx +252 -0
  239. sage/ext/interpreters/wrapper_cdf.cpython-314-x86_64-linux-gnu.so +0 -0
  240. sage/ext/interpreters/wrapper_cdf.pxd +26 -0
  241. sage/ext/interpreters/wrapper_cdf.pyx +245 -0
  242. sage/ext/interpreters/wrapper_rdf.cpython-314-x86_64-linux-gnu.so +0 -0
  243. sage/ext/interpreters/wrapper_rdf.pxd +23 -0
  244. sage/ext/interpreters/wrapper_rdf.pyx +221 -0
  245. sage/ext/interpreters/wrapper_rr.cpython-314-x86_64-linux-gnu.so +0 -0
  246. sage/ext/interpreters/wrapper_rr.pxd +28 -0
  247. sage/ext/interpreters/wrapper_rr.pyx +335 -0
  248. sage/geometry/all__sagemath_modules.py +5 -0
  249. sage/geometry/toric_lattice.py +1745 -0
  250. sage/geometry/toric_lattice_element.cpython-314-x86_64-linux-gnu.so +0 -0
  251. sage/geometry/toric_lattice_element.pyx +432 -0
  252. sage/groups/abelian_gps/abelian_group.py +1925 -0
  253. sage/groups/abelian_gps/abelian_group_element.py +164 -0
  254. sage/groups/abelian_gps/all__sagemath_modules.py +5 -0
  255. sage/groups/abelian_gps/dual_abelian_group.py +421 -0
  256. sage/groups/abelian_gps/dual_abelian_group_element.py +179 -0
  257. sage/groups/abelian_gps/element_base.py +341 -0
  258. sage/groups/abelian_gps/values.py +488 -0
  259. sage/groups/additive_abelian/additive_abelian_group.py +476 -0
  260. sage/groups/additive_abelian/additive_abelian_wrapper.py +857 -0
  261. sage/groups/additive_abelian/all.py +4 -0
  262. sage/groups/additive_abelian/qmodnz.py +231 -0
  263. sage/groups/additive_abelian/qmodnz_element.py +349 -0
  264. sage/groups/affine_gps/affine_group.py +535 -0
  265. sage/groups/affine_gps/all.py +1 -0
  266. sage/groups/affine_gps/catalog.py +17 -0
  267. sage/groups/affine_gps/euclidean_group.py +246 -0
  268. sage/groups/affine_gps/group_element.py +562 -0
  269. sage/groups/all__sagemath_modules.py +12 -0
  270. sage/groups/galois_group.py +479 -0
  271. sage/groups/matrix_gps/all.py +4 -0
  272. sage/groups/matrix_gps/all__sagemath_modules.py +13 -0
  273. sage/groups/matrix_gps/catalog.py +26 -0
  274. sage/groups/matrix_gps/coxeter_group.py +927 -0
  275. sage/groups/matrix_gps/finitely_generated.py +487 -0
  276. sage/groups/matrix_gps/group_element.cpython-314-x86_64-linux-gnu.so +0 -0
  277. sage/groups/matrix_gps/group_element.pxd +11 -0
  278. sage/groups/matrix_gps/group_element.pyx +431 -0
  279. sage/groups/matrix_gps/linear.py +440 -0
  280. sage/groups/matrix_gps/matrix_group.py +617 -0
  281. sage/groups/matrix_gps/named_group.py +296 -0
  282. sage/groups/matrix_gps/orthogonal.py +544 -0
  283. sage/groups/matrix_gps/symplectic.py +251 -0
  284. sage/groups/matrix_gps/unitary.py +436 -0
  285. sage/groups/misc_gps/all__sagemath_modules.py +1 -0
  286. sage/groups/misc_gps/argument_groups.py +1905 -0
  287. sage/groups/misc_gps/imaginary_groups.py +479 -0
  288. sage/groups/perm_gps/all__sagemath_modules.py +1 -0
  289. sage/groups/perm_gps/partn_ref/all__sagemath_modules.py +1 -0
  290. sage/groups/perm_gps/partn_ref/refinement_binary.cpython-314-x86_64-linux-gnu.so +0 -0
  291. sage/groups/perm_gps/partn_ref/refinement_binary.pxd +41 -0
  292. sage/groups/perm_gps/partn_ref/refinement_binary.pyx +1167 -0
  293. sage/groups/perm_gps/partn_ref/refinement_matrices.cpython-314-x86_64-linux-gnu.so +0 -0
  294. sage/groups/perm_gps/partn_ref/refinement_matrices.pxd +31 -0
  295. sage/groups/perm_gps/partn_ref/refinement_matrices.pyx +385 -0
  296. sage/homology/algebraic_topological_model.py +595 -0
  297. sage/homology/all.py +2 -0
  298. sage/homology/all__sagemath_modules.py +8 -0
  299. sage/homology/chain_complex.py +2148 -0
  300. sage/homology/chain_complex_homspace.py +165 -0
  301. sage/homology/chain_complex_morphism.py +629 -0
  302. sage/homology/chain_homotopy.py +604 -0
  303. sage/homology/chains.py +653 -0
  304. sage/homology/free_resolution.py +923 -0
  305. sage/homology/graded_resolution.py +567 -0
  306. sage/homology/hochschild_complex.py +756 -0
  307. sage/homology/homology_group.py +188 -0
  308. sage/homology/homology_morphism.py +422 -0
  309. sage/homology/homology_vector_space_with_basis.py +1454 -0
  310. sage/homology/koszul_complex.py +169 -0
  311. sage/homology/matrix_utils.py +205 -0
  312. sage/libs/all__sagemath_modules.py +1 -0
  313. sage/libs/gsl/__init__.py +1 -0
  314. sage/libs/gsl/airy.pxd +56 -0
  315. sage/libs/gsl/all.pxd +66 -0
  316. sage/libs/gsl/array.cpython-314-x86_64-linux-gnu.so +0 -0
  317. sage/libs/gsl/array.pxd +5 -0
  318. sage/libs/gsl/array.pyx +102 -0
  319. sage/libs/gsl/bessel.pxd +208 -0
  320. sage/libs/gsl/blas.pxd +116 -0
  321. sage/libs/gsl/blas_types.pxd +34 -0
  322. sage/libs/gsl/block.pxd +52 -0
  323. sage/libs/gsl/chebyshev.pxd +37 -0
  324. sage/libs/gsl/clausen.pxd +12 -0
  325. sage/libs/gsl/combination.pxd +47 -0
  326. sage/libs/gsl/complex.pxd +151 -0
  327. sage/libs/gsl/coulomb.pxd +30 -0
  328. sage/libs/gsl/coupling.pxd +21 -0
  329. sage/libs/gsl/dawson.pxd +12 -0
  330. sage/libs/gsl/debye.pxd +24 -0
  331. sage/libs/gsl/dilog.pxd +14 -0
  332. sage/libs/gsl/eigen.pxd +46 -0
  333. sage/libs/gsl/elementary.pxd +12 -0
  334. sage/libs/gsl/ellint.pxd +48 -0
  335. sage/libs/gsl/elljac.pxd +8 -0
  336. sage/libs/gsl/erf.pxd +32 -0
  337. sage/libs/gsl/errno.pxd +26 -0
  338. sage/libs/gsl/exp.pxd +44 -0
  339. sage/libs/gsl/expint.pxd +44 -0
  340. sage/libs/gsl/fermi_dirac.pxd +44 -0
  341. sage/libs/gsl/fft.pxd +121 -0
  342. sage/libs/gsl/fit.pxd +50 -0
  343. sage/libs/gsl/gamma.pxd +94 -0
  344. sage/libs/gsl/gegenbauer.pxd +26 -0
  345. sage/libs/gsl/histogram.pxd +176 -0
  346. sage/libs/gsl/hyperg.pxd +52 -0
  347. sage/libs/gsl/integration.pxd +69 -0
  348. sage/libs/gsl/interp.pxd +109 -0
  349. sage/libs/gsl/laguerre.pxd +24 -0
  350. sage/libs/gsl/lambert.pxd +16 -0
  351. sage/libs/gsl/legendre.pxd +90 -0
  352. sage/libs/gsl/linalg.pxd +185 -0
  353. sage/libs/gsl/log.pxd +26 -0
  354. sage/libs/gsl/math.pxd +43 -0
  355. sage/libs/gsl/matrix.pxd +143 -0
  356. sage/libs/gsl/matrix_complex.pxd +130 -0
  357. sage/libs/gsl/min.pxd +67 -0
  358. sage/libs/gsl/monte.pxd +56 -0
  359. sage/libs/gsl/ntuple.pxd +32 -0
  360. sage/libs/gsl/odeiv.pxd +70 -0
  361. sage/libs/gsl/permutation.pxd +78 -0
  362. sage/libs/gsl/poly.pxd +40 -0
  363. sage/libs/gsl/pow_int.pxd +12 -0
  364. sage/libs/gsl/psi.pxd +28 -0
  365. sage/libs/gsl/qrng.pxd +29 -0
  366. sage/libs/gsl/random.pxd +257 -0
  367. sage/libs/gsl/rng.pxd +100 -0
  368. sage/libs/gsl/roots.pxd +72 -0
  369. sage/libs/gsl/sort.pxd +36 -0
  370. sage/libs/gsl/statistics.pxd +59 -0
  371. sage/libs/gsl/sum.pxd +55 -0
  372. sage/libs/gsl/synchrotron.pxd +16 -0
  373. sage/libs/gsl/transport.pxd +24 -0
  374. sage/libs/gsl/trig.pxd +58 -0
  375. sage/libs/gsl/types.pxd +137 -0
  376. sage/libs/gsl/vector.pxd +101 -0
  377. sage/libs/gsl/vector_complex.pxd +83 -0
  378. sage/libs/gsl/wavelet.pxd +49 -0
  379. sage/libs/gsl/zeta.pxd +28 -0
  380. sage/libs/mpc/__init__.pxd +114 -0
  381. sage/libs/mpc/types.pxd +28 -0
  382. sage/libs/mpfr/__init__.pxd +299 -0
  383. sage/libs/mpfr/types.pxd +26 -0
  384. sage/libs/mpmath/__init__.py +1 -0
  385. sage/libs/mpmath/all.py +27 -0
  386. sage/libs/mpmath/all__sagemath_modules.py +1 -0
  387. sage/libs/mpmath/utils.cpython-314-x86_64-linux-gnu.so +0 -0
  388. sage/libs/mpmath/utils.pxd +4 -0
  389. sage/libs/mpmath/utils.pyx +319 -0
  390. sage/matrix/action.cpython-314-x86_64-linux-gnu.so +0 -0
  391. sage/matrix/action.pxd +26 -0
  392. sage/matrix/action.pyx +596 -0
  393. sage/matrix/all.py +9 -0
  394. sage/matrix/args.cpython-314-x86_64-linux-gnu.so +0 -0
  395. sage/matrix/args.pxd +144 -0
  396. sage/matrix/args.pyx +1668 -0
  397. sage/matrix/benchmark.py +1258 -0
  398. sage/matrix/berlekamp_massey.py +95 -0
  399. sage/matrix/compute_J_ideal.py +926 -0
  400. sage/matrix/constructor.cpython-314-x86_64-linux-gnu.so +0 -0
  401. sage/matrix/constructor.pyx +750 -0
  402. sage/matrix/docs.py +430 -0
  403. sage/matrix/echelon_matrix.cpython-314-x86_64-linux-gnu.so +0 -0
  404. sage/matrix/echelon_matrix.pyx +155 -0
  405. sage/matrix/matrix.pxd +2 -0
  406. sage/matrix/matrix0.cpython-314-x86_64-linux-gnu.so +0 -0
  407. sage/matrix/matrix0.pxd +68 -0
  408. sage/matrix/matrix0.pyx +6324 -0
  409. sage/matrix/matrix1.cpython-314-x86_64-linux-gnu.so +0 -0
  410. sage/matrix/matrix1.pxd +8 -0
  411. sage/matrix/matrix1.pyx +2851 -0
  412. sage/matrix/matrix2.cpython-314-x86_64-linux-gnu.so +0 -0
  413. sage/matrix/matrix2.pxd +25 -0
  414. sage/matrix/matrix2.pyx +20181 -0
  415. sage/matrix/matrix_cdv.cpython-314-x86_64-linux-gnu.so +0 -0
  416. sage/matrix/matrix_cdv.pxd +4 -0
  417. sage/matrix/matrix_cdv.pyx +93 -0
  418. sage/matrix/matrix_complex_double_dense.cpython-314-x86_64-linux-gnu.so +0 -0
  419. sage/matrix/matrix_complex_double_dense.pxd +5 -0
  420. sage/matrix/matrix_complex_double_dense.pyx +98 -0
  421. sage/matrix/matrix_dense.cpython-314-x86_64-linux-gnu.so +0 -0
  422. sage/matrix/matrix_dense.pxd +5 -0
  423. sage/matrix/matrix_dense.pyx +343 -0
  424. sage/matrix/matrix_domain_dense.pxd +5 -0
  425. sage/matrix/matrix_domain_sparse.pxd +5 -0
  426. sage/matrix/matrix_double_dense.cpython-314-x86_64-linux-gnu.so +0 -0
  427. sage/matrix/matrix_double_dense.pxd +7 -0
  428. sage/matrix/matrix_double_dense.pyx +3906 -0
  429. sage/matrix/matrix_double_sparse.cpython-314-x86_64-linux-gnu.so +0 -0
  430. sage/matrix/matrix_double_sparse.pxd +6 -0
  431. sage/matrix/matrix_double_sparse.pyx +248 -0
  432. sage/matrix/matrix_generic_dense.cpython-314-x86_64-linux-gnu.so +0 -0
  433. sage/matrix/matrix_generic_dense.pxd +7 -0
  434. sage/matrix/matrix_generic_dense.pyx +354 -0
  435. sage/matrix/matrix_generic_sparse.cpython-314-x86_64-linux-gnu.so +0 -0
  436. sage/matrix/matrix_generic_sparse.pxd +7 -0
  437. sage/matrix/matrix_generic_sparse.pyx +461 -0
  438. sage/matrix/matrix_laurent_mpolynomial_dense.cpython-314-x86_64-linux-gnu.so +0 -0
  439. sage/matrix/matrix_laurent_mpolynomial_dense.pxd +5 -0
  440. sage/matrix/matrix_laurent_mpolynomial_dense.pyx +115 -0
  441. sage/matrix/matrix_misc.py +313 -0
  442. sage/matrix/matrix_numpy_dense.cpython-314-x86_64-linux-gnu.so +0 -0
  443. sage/matrix/matrix_numpy_dense.pxd +14 -0
  444. sage/matrix/matrix_numpy_dense.pyx +450 -0
  445. sage/matrix/matrix_numpy_integer_dense.cpython-314-x86_64-linux-gnu.so +0 -0
  446. sage/matrix/matrix_numpy_integer_dense.pxd +7 -0
  447. sage/matrix/matrix_numpy_integer_dense.pyx +59 -0
  448. sage/matrix/matrix_polynomial_dense.cpython-314-x86_64-linux-gnu.so +0 -0
  449. sage/matrix/matrix_polynomial_dense.pxd +5 -0
  450. sage/matrix/matrix_polynomial_dense.pyx +5341 -0
  451. sage/matrix/matrix_real_double_dense.cpython-314-x86_64-linux-gnu.so +0 -0
  452. sage/matrix/matrix_real_double_dense.pxd +7 -0
  453. sage/matrix/matrix_real_double_dense.pyx +122 -0
  454. sage/matrix/matrix_space.py +2848 -0
  455. sage/matrix/matrix_sparse.cpython-314-x86_64-linux-gnu.so +0 -0
  456. sage/matrix/matrix_sparse.pxd +5 -0
  457. sage/matrix/matrix_sparse.pyx +1222 -0
  458. sage/matrix/matrix_window.cpython-314-x86_64-linux-gnu.so +0 -0
  459. sage/matrix/matrix_window.pxd +37 -0
  460. sage/matrix/matrix_window.pyx +242 -0
  461. sage/matrix/misc_mpfr.cpython-314-x86_64-linux-gnu.so +0 -0
  462. sage/matrix/misc_mpfr.pyx +80 -0
  463. sage/matrix/operation_table.py +1182 -0
  464. sage/matrix/special.py +3666 -0
  465. sage/matrix/strassen.cpython-314-x86_64-linux-gnu.so +0 -0
  466. sage/matrix/strassen.pyx +851 -0
  467. sage/matrix/symplectic_basis.py +541 -0
  468. sage/matrix/template.pxd +6 -0
  469. sage/matrix/tests.py +71 -0
  470. sage/matroids/advanced.py +77 -0
  471. sage/matroids/all.py +13 -0
  472. sage/matroids/basis_exchange_matroid.cpython-314-x86_64-linux-gnu.so +0 -0
  473. sage/matroids/basis_exchange_matroid.pxd +96 -0
  474. sage/matroids/basis_exchange_matroid.pyx +2344 -0
  475. sage/matroids/basis_matroid.cpython-314-x86_64-linux-gnu.so +0 -0
  476. sage/matroids/basis_matroid.pxd +45 -0
  477. sage/matroids/basis_matroid.pyx +1217 -0
  478. sage/matroids/catalog.py +44 -0
  479. sage/matroids/chow_ring.py +473 -0
  480. sage/matroids/chow_ring_ideal.py +849 -0
  481. sage/matroids/circuit_closures_matroid.cpython-314-x86_64-linux-gnu.so +0 -0
  482. sage/matroids/circuit_closures_matroid.pxd +16 -0
  483. sage/matroids/circuit_closures_matroid.pyx +559 -0
  484. sage/matroids/circuits_matroid.cpython-314-x86_64-linux-gnu.so +0 -0
  485. sage/matroids/circuits_matroid.pxd +38 -0
  486. sage/matroids/circuits_matroid.pyx +947 -0
  487. sage/matroids/constructor.py +1086 -0
  488. sage/matroids/database_collections.py +365 -0
  489. sage/matroids/database_matroids.py +5338 -0
  490. sage/matroids/dual_matroid.py +583 -0
  491. sage/matroids/extension.cpython-314-x86_64-linux-gnu.so +0 -0
  492. sage/matroids/extension.pxd +34 -0
  493. sage/matroids/extension.pyx +519 -0
  494. sage/matroids/flats_matroid.cpython-314-x86_64-linux-gnu.so +0 -0
  495. sage/matroids/flats_matroid.pxd +28 -0
  496. sage/matroids/flats_matroid.pyx +715 -0
  497. sage/matroids/gammoid.py +600 -0
  498. sage/matroids/graphic_matroid.cpython-314-x86_64-linux-gnu.so +0 -0
  499. sage/matroids/graphic_matroid.pxd +39 -0
  500. sage/matroids/graphic_matroid.pyx +2024 -0
  501. sage/matroids/lean_matrix.cpython-314-x86_64-linux-gnu.so +0 -0
  502. sage/matroids/lean_matrix.pxd +126 -0
  503. sage/matroids/lean_matrix.pyx +3667 -0
  504. sage/matroids/linear_matroid.cpython-314-x86_64-linux-gnu.so +0 -0
  505. sage/matroids/linear_matroid.pxd +180 -0
  506. sage/matroids/linear_matroid.pyx +6649 -0
  507. sage/matroids/matroid.cpython-314-x86_64-linux-gnu.so +0 -0
  508. sage/matroids/matroid.pxd +243 -0
  509. sage/matroids/matroid.pyx +8759 -0
  510. sage/matroids/matroids_catalog.py +190 -0
  511. sage/matroids/matroids_plot_helpers.py +890 -0
  512. sage/matroids/minor_matroid.py +480 -0
  513. sage/matroids/minorfix.h +9 -0
  514. sage/matroids/named_matroids.py +5 -0
  515. sage/matroids/rank_matroid.py +268 -0
  516. sage/matroids/set_system.cpython-314-x86_64-linux-gnu.so +0 -0
  517. sage/matroids/set_system.pxd +38 -0
  518. sage/matroids/set_system.pyx +800 -0
  519. sage/matroids/transversal_matroid.cpython-314-x86_64-linux-gnu.so +0 -0
  520. sage/matroids/transversal_matroid.pxd +14 -0
  521. sage/matroids/transversal_matroid.pyx +893 -0
  522. sage/matroids/union_matroid.cpython-314-x86_64-linux-gnu.so +0 -0
  523. sage/matroids/union_matroid.pxd +20 -0
  524. sage/matroids/union_matroid.pyx +331 -0
  525. sage/matroids/unpickling.cpython-314-x86_64-linux-gnu.so +0 -0
  526. sage/matroids/unpickling.pyx +843 -0
  527. sage/matroids/utilities.py +809 -0
  528. sage/misc/all__sagemath_modules.py +20 -0
  529. sage/misc/c3.cpython-314-x86_64-linux-gnu.so +0 -0
  530. sage/misc/c3.pyx +238 -0
  531. sage/misc/compat.py +87 -0
  532. sage/misc/element_with_label.py +173 -0
  533. sage/misc/func_persist.py +79 -0
  534. sage/misc/pickle_old.cpython-314-x86_64-linux-gnu.so +0 -0
  535. sage/misc/pickle_old.pyx +19 -0
  536. sage/misc/proof.py +7 -0
  537. sage/misc/replace_dot_all.py +472 -0
  538. sage/misc/sagedoc_conf.py +168 -0
  539. sage/misc/sphinxify.py +167 -0
  540. sage/misc/test_class_pickling.py +85 -0
  541. sage/modules/all.py +42 -0
  542. sage/modules/complex_double_vector.py +25 -0
  543. sage/modules/diamond_cutting.py +380 -0
  544. sage/modules/fg_pid/all.py +1 -0
  545. sage/modules/fg_pid/fgp_element.py +456 -0
  546. sage/modules/fg_pid/fgp_module.py +2091 -0
  547. sage/modules/fg_pid/fgp_morphism.py +550 -0
  548. sage/modules/filtered_vector_space.py +1271 -0
  549. sage/modules/finite_submodule_iter.cpython-314-x86_64-linux-gnu.so +0 -0
  550. sage/modules/finite_submodule_iter.pxd +27 -0
  551. sage/modules/finite_submodule_iter.pyx +452 -0
  552. sage/modules/fp_graded/all.py +1 -0
  553. sage/modules/fp_graded/element.py +346 -0
  554. sage/modules/fp_graded/free_element.py +298 -0
  555. sage/modules/fp_graded/free_homspace.py +53 -0
  556. sage/modules/fp_graded/free_module.py +1060 -0
  557. sage/modules/fp_graded/free_morphism.py +217 -0
  558. sage/modules/fp_graded/homspace.py +563 -0
  559. sage/modules/fp_graded/module.py +1340 -0
  560. sage/modules/fp_graded/morphism.py +1990 -0
  561. sage/modules/fp_graded/steenrod/all.py +1 -0
  562. sage/modules/fp_graded/steenrod/homspace.py +65 -0
  563. sage/modules/fp_graded/steenrod/module.py +477 -0
  564. sage/modules/fp_graded/steenrod/morphism.py +404 -0
  565. sage/modules/fp_graded/steenrod/profile.py +241 -0
  566. sage/modules/free_module.py +8447 -0
  567. sage/modules/free_module_element.cpython-314-x86_64-linux-gnu.so +0 -0
  568. sage/modules/free_module_element.pxd +22 -0
  569. sage/modules/free_module_element.pyx +5445 -0
  570. sage/modules/free_module_homspace.py +369 -0
  571. sage/modules/free_module_integer.py +896 -0
  572. sage/modules/free_module_morphism.py +823 -0
  573. sage/modules/free_module_pseudohomspace.py +352 -0
  574. sage/modules/free_module_pseudomorphism.py +578 -0
  575. sage/modules/free_quadratic_module.py +1706 -0
  576. sage/modules/free_quadratic_module_integer_symmetric.py +1790 -0
  577. sage/modules/matrix_morphism.py +1745 -0
  578. sage/modules/misc.py +103 -0
  579. sage/modules/module_functors.py +192 -0
  580. sage/modules/multi_filtered_vector_space.py +719 -0
  581. sage/modules/ore_module.py +2208 -0
  582. sage/modules/ore_module_element.py +178 -0
  583. sage/modules/ore_module_homspace.py +147 -0
  584. sage/modules/ore_module_morphism.py +968 -0
  585. sage/modules/quotient_module.py +699 -0
  586. sage/modules/real_double_vector.py +22 -0
  587. sage/modules/submodule.py +255 -0
  588. sage/modules/tensor_operations.py +567 -0
  589. sage/modules/torsion_quadratic_module.py +1352 -0
  590. sage/modules/tutorial_free_modules.py +248 -0
  591. sage/modules/vector_complex_double_dense.cpython-314-x86_64-linux-gnu.so +0 -0
  592. sage/modules/vector_complex_double_dense.pxd +6 -0
  593. sage/modules/vector_complex_double_dense.pyx +117 -0
  594. sage/modules/vector_double_dense.cpython-314-x86_64-linux-gnu.so +0 -0
  595. sage/modules/vector_double_dense.pxd +6 -0
  596. sage/modules/vector_double_dense.pyx +604 -0
  597. sage/modules/vector_integer_dense.cpython-314-x86_64-linux-gnu.so +0 -0
  598. sage/modules/vector_integer_dense.pxd +15 -0
  599. sage/modules/vector_integer_dense.pyx +361 -0
  600. sage/modules/vector_integer_sparse.cpython-314-x86_64-linux-gnu.so +0 -0
  601. sage/modules/vector_integer_sparse.pxd +29 -0
  602. sage/modules/vector_integer_sparse.pyx +406 -0
  603. sage/modules/vector_modn_dense.cpython-314-x86_64-linux-gnu.so +0 -0
  604. sage/modules/vector_modn_dense.pxd +12 -0
  605. sage/modules/vector_modn_dense.pyx +394 -0
  606. sage/modules/vector_modn_sparse.cpython-314-x86_64-linux-gnu.so +0 -0
  607. sage/modules/vector_modn_sparse.pxd +21 -0
  608. sage/modules/vector_modn_sparse.pyx +298 -0
  609. sage/modules/vector_numpy_dense.cpython-314-x86_64-linux-gnu.so +0 -0
  610. sage/modules/vector_numpy_dense.pxd +15 -0
  611. sage/modules/vector_numpy_dense.pyx +304 -0
  612. sage/modules/vector_numpy_integer_dense.cpython-314-x86_64-linux-gnu.so +0 -0
  613. sage/modules/vector_numpy_integer_dense.pxd +7 -0
  614. sage/modules/vector_numpy_integer_dense.pyx +54 -0
  615. sage/modules/vector_rational_dense.cpython-314-x86_64-linux-gnu.so +0 -0
  616. sage/modules/vector_rational_dense.pxd +15 -0
  617. sage/modules/vector_rational_dense.pyx +387 -0
  618. sage/modules/vector_rational_sparse.cpython-314-x86_64-linux-gnu.so +0 -0
  619. sage/modules/vector_rational_sparse.pxd +30 -0
  620. sage/modules/vector_rational_sparse.pyx +413 -0
  621. sage/modules/vector_real_double_dense.cpython-314-x86_64-linux-gnu.so +0 -0
  622. sage/modules/vector_real_double_dense.pxd +6 -0
  623. sage/modules/vector_real_double_dense.pyx +126 -0
  624. sage/modules/vector_space_homspace.py +430 -0
  625. sage/modules/vector_space_morphism.py +989 -0
  626. sage/modules/with_basis/all.py +15 -0
  627. sage/modules/with_basis/cell_module.py +494 -0
  628. sage/modules/with_basis/indexed_element.cpython-314-x86_64-linux-gnu.so +0 -0
  629. sage/modules/with_basis/indexed_element.pxd +13 -0
  630. sage/modules/with_basis/indexed_element.pyx +1058 -0
  631. sage/modules/with_basis/invariant.py +1075 -0
  632. sage/modules/with_basis/morphism.py +1636 -0
  633. sage/modules/with_basis/representation.py +2939 -0
  634. sage/modules/with_basis/subquotient.py +685 -0
  635. sage/numerical/all__sagemath_modules.py +6 -0
  636. sage/numerical/gauss_legendre.cpython-314-x86_64-linux-gnu.so +0 -0
  637. sage/numerical/gauss_legendre.pyx +381 -0
  638. sage/numerical/optimize.py +910 -0
  639. sage/probability/all.py +10 -0
  640. sage/probability/probability_distribution.cpython-314-x86_64-linux-gnu.so +0 -0
  641. sage/probability/probability_distribution.pyx +1242 -0
  642. sage/probability/random_variable.py +411 -0
  643. sage/quadratic_forms/all.py +4 -0
  644. sage/quadratic_forms/all__sagemath_modules.py +15 -0
  645. sage/quadratic_forms/binary_qf.py +2042 -0
  646. sage/quadratic_forms/bqf_class_group.py +748 -0
  647. sage/quadratic_forms/constructions.py +93 -0
  648. sage/quadratic_forms/count_local_2.cpython-314-x86_64-linux-gnu.so +0 -0
  649. sage/quadratic_forms/count_local_2.pyx +365 -0
  650. sage/quadratic_forms/extras.py +195 -0
  651. sage/quadratic_forms/quadratic_form.py +1753 -0
  652. sage/quadratic_forms/quadratic_form__count_local_2.py +221 -0
  653. sage/quadratic_forms/quadratic_form__equivalence_testing.py +708 -0
  654. sage/quadratic_forms/quadratic_form__evaluate.cpython-314-x86_64-linux-gnu.so +0 -0
  655. sage/quadratic_forms/quadratic_form__evaluate.pyx +139 -0
  656. sage/quadratic_forms/quadratic_form__local_density_congruence.py +977 -0
  657. sage/quadratic_forms/quadratic_form__local_field_invariants.py +1072 -0
  658. sage/quadratic_forms/quadratic_form__neighbors.py +424 -0
  659. sage/quadratic_forms/quadratic_form__reduction_theory.py +488 -0
  660. sage/quadratic_forms/quadratic_form__split_local_covering.py +416 -0
  661. sage/quadratic_forms/quadratic_form__ternary_Tornaria.py +657 -0
  662. sage/quadratic_forms/quadratic_form__theta.py +352 -0
  663. sage/quadratic_forms/quadratic_form__variable_substitutions.py +370 -0
  664. sage/quadratic_forms/random_quadraticform.py +209 -0
  665. sage/quadratic_forms/ternary.cpython-314-x86_64-linux-gnu.so +0 -0
  666. sage/quadratic_forms/ternary.pyx +1154 -0
  667. sage/quadratic_forms/ternary_qf.py +2027 -0
  668. sage/rings/all__sagemath_modules.py +28 -0
  669. sage/rings/asymptotic/all__sagemath_modules.py +1 -0
  670. sage/rings/asymptotic/misc.py +1252 -0
  671. sage/rings/cc.py +4 -0
  672. sage/rings/cfinite_sequence.py +1306 -0
  673. sage/rings/complex_conversion.cpython-314-x86_64-linux-gnu.so +0 -0
  674. sage/rings/complex_conversion.pxd +8 -0
  675. sage/rings/complex_conversion.pyx +23 -0
  676. sage/rings/complex_double.cpython-314-x86_64-linux-gnu.so +0 -0
  677. sage/rings/complex_double.pxd +21 -0
  678. sage/rings/complex_double.pyx +2654 -0
  679. sage/rings/complex_mpc.cpython-314-x86_64-linux-gnu.so +0 -0
  680. sage/rings/complex_mpc.pxd +21 -0
  681. sage/rings/complex_mpc.pyx +2576 -0
  682. sage/rings/complex_mpfr.cpython-314-x86_64-linux-gnu.so +0 -0
  683. sage/rings/complex_mpfr.pxd +18 -0
  684. sage/rings/complex_mpfr.pyx +3602 -0
  685. sage/rings/derivation.py +2334 -0
  686. sage/rings/finite_rings/all__sagemath_modules.py +1 -0
  687. sage/rings/finite_rings/maps_finite_field.py +191 -0
  688. sage/rings/function_field/all__sagemath_modules.py +8 -0
  689. sage/rings/function_field/derivations.py +102 -0
  690. sage/rings/function_field/derivations_rational.py +132 -0
  691. sage/rings/function_field/differential.py +853 -0
  692. sage/rings/function_field/divisor.py +1107 -0
  693. sage/rings/function_field/drinfeld_modules/action.py +199 -0
  694. sage/rings/function_field/drinfeld_modules/all.py +1 -0
  695. sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py +673 -0
  696. sage/rings/function_field/drinfeld_modules/drinfeld_module.py +2087 -0
  697. sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py +1131 -0
  698. sage/rings/function_field/drinfeld_modules/homset.py +420 -0
  699. sage/rings/function_field/drinfeld_modules/morphism.py +820 -0
  700. sage/rings/function_field/hermite_form_polynomial.cpython-314-x86_64-linux-gnu.so +0 -0
  701. sage/rings/function_field/hermite_form_polynomial.pyx +188 -0
  702. sage/rings/function_field/khuri_makdisi.cpython-314-x86_64-linux-gnu.so +0 -0
  703. sage/rings/function_field/khuri_makdisi.pyx +935 -0
  704. sage/rings/invariants/all.py +4 -0
  705. sage/rings/invariants/invariant_theory.py +4597 -0
  706. sage/rings/invariants/reconstruction.py +395 -0
  707. sage/rings/polynomial/all__sagemath_modules.py +17 -0
  708. sage/rings/polynomial/integer_valued_polynomials.py +1230 -0
  709. sage/rings/polynomial/laurent_polynomial_mpair.cpython-314-x86_64-linux-gnu.so +0 -0
  710. sage/rings/polynomial/laurent_polynomial_mpair.pxd +15 -0
  711. sage/rings/polynomial/laurent_polynomial_mpair.pyx +2023 -0
  712. sage/rings/polynomial/ore_function_element.py +952 -0
  713. sage/rings/polynomial/ore_function_field.py +1028 -0
  714. sage/rings/polynomial/ore_polynomial_element.cpython-314-x86_64-linux-gnu.so +0 -0
  715. sage/rings/polynomial/ore_polynomial_element.pxd +48 -0
  716. sage/rings/polynomial/ore_polynomial_element.pyx +3145 -0
  717. sage/rings/polynomial/ore_polynomial_ring.py +1334 -0
  718. sage/rings/polynomial/polynomial_real_mpfr_dense.cpython-314-x86_64-linux-gnu.so +0 -0
  719. sage/rings/polynomial/polynomial_real_mpfr_dense.pyx +788 -0
  720. sage/rings/polynomial/q_integer_valued_polynomials.py +1264 -0
  721. sage/rings/polynomial/skew_polynomial_element.cpython-314-x86_64-linux-gnu.so +0 -0
  722. sage/rings/polynomial/skew_polynomial_element.pxd +9 -0
  723. sage/rings/polynomial/skew_polynomial_element.pyx +684 -0
  724. sage/rings/polynomial/skew_polynomial_finite_field.cpython-314-x86_64-linux-gnu.so +0 -0
  725. sage/rings/polynomial/skew_polynomial_finite_field.pxd +19 -0
  726. sage/rings/polynomial/skew_polynomial_finite_field.pyx +1093 -0
  727. sage/rings/polynomial/skew_polynomial_finite_order.cpython-314-x86_64-linux-gnu.so +0 -0
  728. sage/rings/polynomial/skew_polynomial_finite_order.pxd +10 -0
  729. sage/rings/polynomial/skew_polynomial_finite_order.pyx +567 -0
  730. sage/rings/polynomial/skew_polynomial_ring.py +908 -0
  731. sage/rings/real_double_element_gsl.cpython-314-x86_64-linux-gnu.so +0 -0
  732. sage/rings/real_double_element_gsl.pxd +8 -0
  733. sage/rings/real_double_element_gsl.pyx +794 -0
  734. sage/rings/real_field.py +58 -0
  735. sage/rings/real_mpfr.cpython-314-x86_64-linux-gnu.so +0 -0
  736. sage/rings/real_mpfr.pxd +29 -0
  737. sage/rings/real_mpfr.pyx +6122 -0
  738. sage/rings/ring_extension.cpython-314-x86_64-linux-gnu.so +0 -0
  739. sage/rings/ring_extension.pxd +42 -0
  740. sage/rings/ring_extension.pyx +2779 -0
  741. sage/rings/ring_extension_conversion.cpython-314-x86_64-linux-gnu.so +0 -0
  742. sage/rings/ring_extension_conversion.pxd +16 -0
  743. sage/rings/ring_extension_conversion.pyx +462 -0
  744. sage/rings/ring_extension_element.cpython-314-x86_64-linux-gnu.so +0 -0
  745. sage/rings/ring_extension_element.pxd +21 -0
  746. sage/rings/ring_extension_element.pyx +1635 -0
  747. sage/rings/ring_extension_homset.py +64 -0
  748. sage/rings/ring_extension_morphism.cpython-314-x86_64-linux-gnu.so +0 -0
  749. sage/rings/ring_extension_morphism.pxd +35 -0
  750. sage/rings/ring_extension_morphism.pyx +920 -0
  751. sage/schemes/all__sagemath_modules.py +1 -0
  752. sage/schemes/projective/all__sagemath_modules.py +1 -0
  753. sage/schemes/projective/coherent_sheaf.py +300 -0
  754. sage/schemes/projective/cohomology.py +510 -0
  755. sage/stats/all.py +15 -0
  756. sage/stats/basic_stats.py +489 -0
  757. sage/stats/distributions/all.py +7 -0
  758. sage/stats/distributions/catalog.py +34 -0
  759. sage/stats/distributions/dgs.h +50 -0
  760. sage/stats/distributions/dgs.pxd +111 -0
  761. sage/stats/distributions/dgs_bern.h +400 -0
  762. sage/stats/distributions/dgs_gauss.h +614 -0
  763. sage/stats/distributions/dgs_misc.h +104 -0
  764. sage/stats/distributions/discrete_gaussian_integer.cpython-314-x86_64-linux-gnu.so +0 -0
  765. sage/stats/distributions/discrete_gaussian_integer.pxd +14 -0
  766. sage/stats/distributions/discrete_gaussian_integer.pyx +498 -0
  767. sage/stats/distributions/discrete_gaussian_lattice.py +908 -0
  768. sage/stats/distributions/discrete_gaussian_polynomial.py +141 -0
  769. sage/stats/hmm/all.py +15 -0
  770. sage/stats/hmm/chmm.cpython-314-x86_64-linux-gnu.so +0 -0
  771. sage/stats/hmm/chmm.pyx +1595 -0
  772. sage/stats/hmm/distributions.cpython-314-x86_64-linux-gnu.so +0 -0
  773. sage/stats/hmm/distributions.pxd +29 -0
  774. sage/stats/hmm/distributions.pyx +531 -0
  775. sage/stats/hmm/hmm.cpython-314-x86_64-linux-gnu.so +0 -0
  776. sage/stats/hmm/hmm.pxd +17 -0
  777. sage/stats/hmm/hmm.pyx +1388 -0
  778. sage/stats/hmm/util.cpython-314-x86_64-linux-gnu.so +0 -0
  779. sage/stats/hmm/util.pxd +7 -0
  780. sage/stats/hmm/util.pyx +165 -0
  781. sage/stats/intlist.cpython-314-x86_64-linux-gnu.so +0 -0
  782. sage/stats/intlist.pxd +14 -0
  783. sage/stats/intlist.pyx +588 -0
  784. sage/stats/r.py +49 -0
  785. sage/stats/time_series.cpython-314-x86_64-linux-gnu.so +0 -0
  786. sage/stats/time_series.pxd +6 -0
  787. sage/stats/time_series.pyx +2546 -0
  788. sage/tensor/all.py +2 -0
  789. sage/tensor/modules/all.py +8 -0
  790. sage/tensor/modules/alternating_contr_tensor.py +761 -0
  791. sage/tensor/modules/comp.py +5598 -0
  792. sage/tensor/modules/ext_pow_free_module.py +824 -0
  793. sage/tensor/modules/finite_rank_free_module.py +3589 -0
  794. sage/tensor/modules/format_utilities.py +333 -0
  795. sage/tensor/modules/free_module_alt_form.py +858 -0
  796. sage/tensor/modules/free_module_automorphism.py +1207 -0
  797. sage/tensor/modules/free_module_basis.py +1074 -0
  798. sage/tensor/modules/free_module_element.py +284 -0
  799. sage/tensor/modules/free_module_homset.py +652 -0
  800. sage/tensor/modules/free_module_linear_group.py +564 -0
  801. sage/tensor/modules/free_module_morphism.py +1581 -0
  802. sage/tensor/modules/free_module_tensor.py +3289 -0
  803. sage/tensor/modules/reflexive_module.py +386 -0
  804. sage/tensor/modules/tensor_free_module.py +780 -0
  805. sage/tensor/modules/tensor_free_submodule.py +538 -0
  806. sage/tensor/modules/tensor_free_submodule_basis.py +140 -0
  807. sage/tensor/modules/tensor_with_indices.py +1043 -0
sage/stats/hmm/hmm.pyx ADDED
@@ -0,0 +1,1388 @@
1
+ # sage_setup: distribution = sagemath-modules
2
+ # sage.doctest: needs numpy sage.modules
3
+ r"""
4
+ Hidden Markov Models
5
+
6
+ This is a complete pure-Cython optimized implementation of Hidden
7
+ Markov Models. It fully supports Discrete, Gaussian, and Mixed
8
+ Gaussian emissions.
9
+
10
+ The best references for the basic HMM algorithms implemented here are:
11
+
12
+ - Tapas Kanungo's "Hidden Markov Models"
13
+
14
+ - Jackson's HMM tutorial:
15
+ http://personal.ee.surrey.ac.uk/Personal/P.Jackson/tutorial/
16
+
17
+ LICENSE: Some of the code in this file is based on reading Kanungo's
18
+ GPLv2+ implementation of discrete HMM's, hence the present code must
19
+ be licensed with a GPLv2+ compatible license.
20
+
21
+ AUTHOR:
22
+
23
+ - William Stein, 2010-03
24
+ """
25
+
26
+ # ****************************************************************************
27
+ # Copyright (C) 2010 William Stein <wstein@gmail.com>
28
+ #
29
+ # This program is free software: you can redistribute it and/or modify
30
+ # it under the terms of the GNU General Public License as published by
31
+ # the Free Software Foundation, either version 2 of the License, or
32
+ # (at your option) any later version.
33
+ # https://www.gnu.org/licenses/
34
+ # ****************************************************************************
35
+
36
+ from libc.math cimport log
37
+ from cysignals.signals cimport sig_on, sig_off
38
+
39
+ from sage.stats.time_series cimport TimeSeries
40
+ from sage.structure.element import Matrix
41
+ from sage.matrix.constructor import matrix
42
+ from sage.misc.randstate cimport current_randstate, randstate
43
+ from cpython.object cimport PyObject_RichCompare
44
+
45
+ from sage.stats.hmm.util cimport HMM_Util
46
+
47
+ cdef HMM_Util util = HMM_Util()
48
+
49
+ ###########################################
50
+
51
+ cdef class HiddenMarkovModel:
52
+ r"""
53
+ Abstract base class for all Hidden Markov Models.
54
+ """
55
+ def initial_probabilities(self):
56
+ r"""
57
+ Return the initial probabilities as a :class:`TimeSeries` of
58
+ length `N`, where `N` is the number of states of the Markov model.
59
+
60
+ EXAMPLES::
61
+
62
+ sage: m = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]],
63
+ ....: [[0.1,0.9],[0.5,0.5]],
64
+ ....: [.2,.8])
65
+ sage: pi = m.initial_probabilities(); pi
66
+ [0.2000, 0.8000]
67
+ sage: type(pi)
68
+ <... 'sage.stats.time_series.TimeSeries'>
69
+
70
+ The returned time series is a copy, so changing it does not
71
+ change the model::
72
+
73
+ sage: pi[0] = .1; pi[1] = .9
74
+ sage: m.initial_probabilities()
75
+ [0.2000, 0.8000]
76
+
77
+ Some other models::
78
+
79
+ sage: m = hmm.GaussianHiddenMarkovModel([[.1,.9],[.5,.5]],
80
+ ....: [(1,1), (-1,1)],
81
+ ....: [.1,.9])
82
+ sage: m.initial_probabilities()
83
+ [0.1000, 0.9000]
84
+ sage: m = hmm.GaussianMixtureHiddenMarkovModel(
85
+ ....: [[.9,.1],[.4,.6]],
86
+ ....: [[(.4,(0,1)), (.6,(1,0.1))], [(1,(0,1))]],
87
+ ....: [.7,.3])
88
+ sage: m.initial_probabilities()
89
+ [0.7000, 0.3000]
90
+ """
91
+ return TimeSeries(self.pi)
92
+
93
+ def transition_matrix(self):
94
+ r"""
95
+ Return the state transition matrix.
96
+
97
+ OUTPUT: a Sage matrix with real double precision (RDF) entries.
98
+
99
+ EXAMPLES::
100
+
101
+ sage: M = hmm.DiscreteHiddenMarkovModel([[0.7,0.3],[0.9,0.1]],
102
+ ....: [[0.5,.5],[.1,.9]],
103
+ ....: [0.3,0.7])
104
+ sage: T = M.transition_matrix(); T
105
+ [0.7 0.3]
106
+ [0.9 0.1]
107
+
108
+ The returned matrix is mutable, but changing it does not
109
+ change the transition matrix for the model::
110
+
111
+ sage: T[0,0] = .1; T[0,1] = .9
112
+ sage: M.transition_matrix()
113
+ [0.7 0.3]
114
+ [0.9 0.1]
115
+
116
+ Transition matrices for other types of models::
117
+
118
+ sage: M = hmm.GaussianHiddenMarkovModel([[.1,.9],[.5,.5]],
119
+ ....: [(1,1), (-1,1)],
120
+ ....: [.5,.5])
121
+ sage: M.transition_matrix()
122
+ [0.1 0.9]
123
+ [0.5 0.5]
124
+ sage: M = hmm.GaussianMixtureHiddenMarkovModel(
125
+ ....: [[.9,.1],[.4,.6]],
126
+ ....: [[(.4,(0,1)), (.6,(1,0.1))],[(1,(0,1))]],
127
+ ....: [.7,.3])
128
+ sage: M.transition_matrix()
129
+ [0.9 0.1]
130
+ [0.4 0.6]
131
+ """
132
+ from sage.matrix.constructor import matrix
133
+ from sage.rings.real_double import RDF
134
+ return matrix(RDF, self.N, self.A.list())
135
+
136
+ def graph(self, eps=1e-3):
137
+ r"""
138
+ Create a weighted directed graph from the transition matrix,
139
+ not including any edge with a probability less than ``eps``.
140
+
141
+ INPUT:
142
+
143
+ - ``eps`` -- nonnegative real number
144
+
145
+ OUTPUT: a :class:`DiGraph`
146
+
147
+ EXAMPLES::
148
+
149
+ sage: m = hmm.DiscreteHiddenMarkovModel([[.3,0,.7],[0,0,1],[.5,.5,0]],
150
+ ....: [[.5,.5,.2]]*3,
151
+ ....: [1/3]*3)
152
+ sage: G = m.graph(); G # needs sage.graphs
153
+ Looped digraph on 3 vertices
154
+ sage: G.edges(sort=True) # needs sage.graphs
155
+ [(0, 0, 0.3), (0, 2, 0.7), (1, 2, 1.0), (2, 0, 0.5), (2, 1, 0.5)]
156
+ sage: G.plot() # needs sage.graphs sage.plot
157
+ Graphics object consisting of 11 graphics primitives
158
+ """
159
+ cdef int i, j
160
+ m = self.transition_matrix()
161
+ for i in range(self.N):
162
+ for j in range(self.N):
163
+ if m[i,j] < eps:
164
+ m[i,j] = 0
165
+ from sage.graphs.digraph import DiGraph
166
+ return DiGraph(m, weighted=True)
167
+
168
+ def sample(self, Py_ssize_t length, number=None, starting_state=None):
169
+ r"""
170
+ Return number samples from this HMM of given length.
171
+
172
+ INPUT:
173
+
174
+ - ``length`` -- positive integer
175
+ - ``number`` -- (default: ``None``) if given, compute list of this many
176
+ sample sequences
177
+ - ``starting_state`` -- integer (or ``None``); if specified, generate a
178
+ sequence using this model starting with the given state instead of
179
+ the initial probabilities to determine the starting state
180
+
181
+ OUTPUT:
182
+
183
+ - if ``number`` is not given, return a single :class:`TimeSeries`.
184
+ - if ``number`` is given, return a list of :class:`TimeSeries`.
185
+
186
+ EXAMPLES::
187
+
188
+ sage: set_random_seed(0)
189
+ sage: a = hmm.DiscreteHiddenMarkovModel([[0.1,0.9],[0.1,0.9]],
190
+ ....: [[1,0],[0,1]],
191
+ ....: [0,1])
192
+ sage: print(a.sample(10, 3))
193
+ [[1, 0, 1, 1, 1, 1, 0, 1, 1, 1],
194
+ [1, 1, 0, 0, 1, 1, 1, 1, 1, 1],
195
+ [1, 1, 1, 1, 0, 1, 0, 1, 1, 1]]
196
+ sage: a.sample(15)
197
+ [1, 1, 1, 1, 0 ... 1, 1, 1, 1, 1]
198
+ sage: a.sample(3, 1)
199
+ [[1, 1, 1]]
200
+ sage: list(a.sample(1000)).count(0)
201
+ 88
202
+
203
+ If the emission symbols are set::
204
+
205
+ sage: set_random_seed(0)
206
+ sage: a = hmm.DiscreteHiddenMarkovModel([[0.5,0.5],[0.1,0.9]],
207
+ ....: [[1,0],[0,1]], [0,1],
208
+ ....: ['up', 'down'])
209
+ sage: a.sample(10)
210
+ ['down', 'up', 'down', 'down', 'down', 'down', 'up', 'up', 'up', 'up']
211
+
212
+ Force a starting state::
213
+
214
+ sage: set_random_seed(0); a.sample(10, starting_state=0)
215
+ ['up', 'up', 'down', 'down', 'down', 'down', 'up', 'up', 'up', 'up']
216
+ """
217
+ if number is None:
218
+ return self.generate_sequence(length, starting_state=starting_state)[0]
219
+
220
+ cdef Py_ssize_t i
221
+ return [self.generate_sequence(length, starting_state=starting_state)[0] for i in range(number)]
222
+
223
+ #########################################################
224
+ # Some internal functions used for various general
225
+ # HMM algorithms.
226
+ #########################################################
227
+ cdef TimeSeries _baum_welch_gamma(self, TimeSeries alpha, TimeSeries beta):
228
+ r"""
229
+ Used internally to compute the scaled quantity gamma_t(j)
230
+ appearing in the Baum-Welch reestimation algorithm.
231
+
232
+ The quantity gamma_t(j) is the (scaled!) probability of being
233
+ in state j at time t, given the observation sequence.
234
+
235
+ INPUT:
236
+
237
+ - ``alpha`` -- :class:`TimeSeries` as output by the scaled forward algorithm
238
+ - ``beta`` -- :class:`TimeSeries` as output by the scaled backward algorithm
239
+
240
+ OUTPUT: :class:`TimeSeries` gamma such that gamma[t*N+j] is gamma_t(j).
241
+ """
242
+ cdef int j, N = self.N
243
+ cdef Py_ssize_t t, T = alpha._length//N
244
+ cdef TimeSeries gamma = TimeSeries(alpha._length, initialize=False)
245
+ cdef double denominator
246
+ sig_on()
247
+ for t in range(T):
248
+ denominator = 0
249
+ for j in range(N):
250
+ gamma._values[t*N + j] = alpha._values[t*N + j] * beta._values[t*N + j]
251
+ denominator += gamma._values[t*N + j]
252
+ for j in range(N):
253
+ gamma._values[t*N + j] /= denominator
254
+ sig_off()
255
+ return gamma
256
+
257
+
258
+ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel):
259
+ r"""
260
+ A discrete Hidden Markov model implemented using double precision
261
+ floating point arithmetic.
262
+
263
+ INPUT:
264
+
265
+ - ``A`` -- list of lists or a square `N \times N` matrix, whose
266
+ `(i,j)` entry gives the probability of transitioning from
267
+ state `i` to state `j`.
268
+
269
+ - ``B`` -- list of `N` lists or a matrix with `N` rows, such that
270
+ `B[i,k]` gives the probability of emitting symbol `k` while
271
+ in state `i`.
272
+
273
+ - ``pi`` -- the probabilities of starting in each initial
274
+ state, i.e., ``pi[i]`` is the probability of starting in
275
+ state `i`.
276
+
277
+ - ``emission_symbols`` -- ``None`` or list (default: ``None``); if
278
+ None, the emission_symbols are the ints ``[0..N-1]``, where `N`
279
+ is the number of states. Otherwise, they are the entries
280
+ of the list ``emissions_symbols``, which must all be hashable.
281
+
282
+ - ``normalize`` -- boolean (default: ``True``); if given, input is
283
+ normalized to define valid probability distributions,
284
+ e.g., the entries of `A` are made nonnegative and the rows
285
+ sum to 1, and the probabilities in ``pi`` are normalized.
286
+
287
+ EXAMPLES::
288
+
289
+ sage: m = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]],
290
+ ....: [[0.1,0.9],[0.5,0.5]],
291
+ ....: [.5,.5]); m
292
+ Discrete Hidden Markov Model with 2 States and 2 Emissions
293
+ Transition matrix:
294
+ [0.4 0.6]
295
+ [0.1 0.9]
296
+ Emission matrix:
297
+ [0.1 0.9]
298
+ [0.5 0.5]
299
+ Initial probabilities: [0.5000, 0.5000]
300
+ sage: m.log_likelihood([0,1,0,1,0,1])
301
+ -4.66693474691329...
302
+ sage: m.viterbi([0,1,0,1,0,1])
303
+ ([1, 1, 1, 1, 1, 1], -5.378832842208748)
304
+ sage: m.baum_welch([0,1,0,1,0,1])
305
+ (0.0, 22)
306
+ sage: m # rel tol 1e-10
307
+ Discrete Hidden Markov Model with 2 States and 2 Emissions
308
+ Transition matrix:
309
+ [1.0134345614745788e-70 1.0]
310
+ [ 1.0 3.9974352713558623e-19]
311
+ Emission matrix:
312
+ [ 7.380221566254936e-54 1.0]
313
+ [ 1.0 3.9974352626002193e-19]
314
+ Initial probabilities: [0.0000, 1.0000]
315
+ sage: m.sample(10)
316
+ [0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
317
+ sage: m.graph().plot() # needs sage.plot
318
+ Graphics object consisting of 6 graphics primitives
319
+
320
+ A 3-state model that happens to always outputs 'b'::
321
+
322
+ sage: m = hmm.DiscreteHiddenMarkovModel([[1/3]*3]*3, [[0,1,0]]*3, [1/3]*3, ['a','b','c'])
323
+ sage: m.sample(10)
324
+ ['b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b']
325
+ """
326
+ cdef TimeSeries B
327
+ cdef int n_out
328
+ cdef object _emission_symbols, _emission_symbols_dict
329
+
330
+ def __init__(self, A, B, pi, emission_symbols=None, bint normalize=True):
331
+ r"""
332
+ Create a discrete emissions HMM with transition probability
333
+ matrix A, emission probabilities given by B, initial state
334
+ probabilities pi, and given emission symbols (which default
335
+ to the first few nonnegative integers).
336
+
337
+ EXAMPLES::
338
+
339
+ sage: hmm.DiscreteHiddenMarkovModel([.5,0,-1,.5], [[1],[1]],[.5,.5]).transition_matrix()
340
+ [1.0 0.0]
341
+ [0.0 1.0]
342
+ sage: hmm.DiscreteHiddenMarkovModel([0,0,.1,.9], [[1],[1]],[.5,.5]).transition_matrix()
343
+ [0.5 0.5]
344
+ [0.1 0.9]
345
+ sage: hmm.DiscreteHiddenMarkovModel([-1,-2,.1,.9], [[1],[1]],[.5,.5]).transition_matrix()
346
+ [0.5 0.5]
347
+ [0.1 0.9]
348
+ sage: hmm.DiscreteHiddenMarkovModel([1,2,.1,1.2], [[1],[1]],[.5,.5]).transition_matrix()
349
+ [ 0.3333333333333333 0.6666666666666666]
350
+ [0.07692307692307693 0.923076923076923]
351
+ """
352
+ self.pi = util.initial_probs_to_TimeSeries(pi, normalize)
353
+ self.N = len(self.pi)
354
+ self.A = util.state_matrix_to_TimeSeries(A, self.N, normalize)
355
+ self._emission_symbols = emission_symbols
356
+ if self._emission_symbols is not None:
357
+ self._emission_symbols_dict = dict([(y,x) for x,y in enumerate(emission_symbols)])
358
+
359
+ if not isinstance(B, Matrix):
360
+ B = matrix(B)
361
+ if B.nrows() != self.N:
362
+ raise ValueError("number of rows of B must equal number of states")
363
+ self.B = TimeSeries(B.list())
364
+ self.n_out = B.ncols()
365
+ if emission_symbols is not None and len(emission_symbols) != self.n_out:
366
+ raise ValueError("number of emission symbols must equal number of output states")
367
+ cdef Py_ssize_t i
368
+ if normalize:
369
+ for i in range(self.N):
370
+ util.normalize_probability_TimeSeries(self.B, i*self.n_out, (i+1)*self.n_out)
371
+
372
+ def __reduce__(self):
373
+ r"""
374
+ Used in pickling.
375
+
376
+ EXAMPLES::
377
+
378
+ sage: m = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]], [[0.0,1.0],[1,1]], [0,1], ['a','b'])
379
+ sage: loads(dumps(m)) == m
380
+ True
381
+ """
382
+ return unpickle_discrete_hmm_v1, \
383
+ (self.A, self.B, self.pi, self.n_out, self._emission_symbols, self._emission_symbols_dict)
384
+
385
+ def __richcmp__(self, other, op):
386
+ r"""
387
+ EXAMPLES::
388
+
389
+ sage: m = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]], [[0.0,1.0],[0.5,0.5]], [.5,.5])
390
+ sage: n = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]], [[0.0,1.0],[0.5,0.5]], [1,0])
391
+ sage: m == n
392
+ False
393
+ sage: m == m
394
+ True
395
+ sage: m < n
396
+ True
397
+ sage: n < m
398
+ False
399
+ """
400
+ if not isinstance(other, DiscreteHiddenMarkovModel):
401
+ return NotImplemented
402
+ return PyObject_RichCompare(self.__reduce__()[1],
403
+ other.__reduce__()[1], op)
404
+
405
+ def emission_matrix(self):
406
+ r"""
407
+ Return the matrix whose `i`-th row specifies the emission
408
+ probability distribution for the `i`-th state.
409
+
410
+ More precisely,
411
+ the `i,j` entry of the matrix is the probability of the Markov
412
+ model outputting the `j`-th symbol when it is in the `i`-th state.
413
+
414
+ OUTPUT: a Sage matrix with real double precision (RDF) entries.
415
+
416
+ EXAMPLES::
417
+
418
+ sage: m = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]],
419
+ ....: [[0.1,0.9],[0.5,0.5]],
420
+ ....: [.5,.5])
421
+ sage: E = m.emission_matrix(); E
422
+ [0.1 0.9]
423
+ [0.5 0.5]
424
+
425
+ The returned matrix is mutable, but changing it does not
426
+ change the transition matrix for the model::
427
+
428
+ sage: E[0,0] = 0; E[0,1] = 1
429
+ sage: m.emission_matrix()
430
+ [0.1 0.9]
431
+ [0.5 0.5]
432
+ """
433
+ from sage.matrix.constructor import matrix
434
+ from sage.rings.real_double import RDF
435
+ return matrix(RDF, self.N, self.n_out, self.B.list())
436
+
437
+ def __repr__(self):
438
+ r"""
439
+ Return string representation of this discrete hidden Markov model.
440
+
441
+ EXAMPLES::
442
+
443
+ sage: m = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]], [[0.1,0.9],[0.5,0.5]], [.2,.8])
444
+ sage: m.__repr__()
445
+ 'Discrete Hidden Markov Model with 2 States and 2 Emissions\nTransition matrix:\n[0.4 0.6]\n[0.1 0.9]\nEmission matrix:\n[0.1 0.9]\n[0.5 0.5]\nInitial probabilities: [0.2000, 0.8000]'
446
+ """
447
+ s = "Discrete Hidden Markov Model with %s States and %s Emissions" % (
448
+ self.N, self.n_out)
449
+ s += '\nTransition matrix:\n%s' % self.transition_matrix()
450
+ s += '\nEmission matrix:\n%s' % self.emission_matrix()
451
+ s += '\nInitial probabilities: %s' % self.initial_probabilities()
452
+ if self._emission_symbols is not None:
453
+ s += '\nEmission symbols: %s' % self._emission_symbols
454
+ return s
455
+
456
+ def _emission_symbols_to_IntList(self, obs):
457
+ r"""
458
+ Internal function used to convert a list of emission symbols to an :class:`IntList`.
459
+
460
+ INPUT:
461
+
462
+ - ``obs`` -- list of objects
463
+
464
+ OUTPUT: an IntList
465
+
466
+ EXAMPLES::
467
+
468
+ sage: m = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]], [[0.1,0.9],[0.5,0.5]], [.2,.8], ['smile', 'frown'])
469
+ sage: m._emission_symbols_to_IntList(['frown','smile'])
470
+ [1, 0]
471
+ """
472
+ d = self._emission_symbols_dict
473
+ return IntList([d[x] for x in obs])
474
+
475
+ def _IntList_to_emission_symbols(self, obs):
476
+ r"""
477
+ Internal function used to convert a list of emission symbols to an IntList.
478
+
479
+ INPUT:
480
+
481
+ - ``obs`` -- list of objects
482
+
483
+ OUTPUT: an IntList
484
+
485
+ EXAMPLES::
486
+
487
+ sage: m = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]], [[0.1,0.9],[0.5,0.5]], [.2,.8], ['smile', 'frown'])
488
+ sage: m._IntList_to_emission_symbols(stats.IntList([0,0,1,0]))
489
+ ['smile', 'smile', 'frown', 'smile']
490
+ """
491
+ d = self._emission_symbols
492
+ return [d[x] for x in obs]
493
+
494
+ def log_likelihood(self, obs, bint scale=True):
495
+ r"""
496
+ Return the logarithm of the probability that this model produced the given
497
+ observation sequence. Thus the output is a nonpositive number.
498
+
499
+ INPUT:
500
+
501
+ - ``obs`` -- sequence of observations
502
+
503
+ - ``scale`` -- boolean (default: ``True``); if ``True``, use rescaling
504
+ to overoid loss of precision due to the very limited
505
+ dynamic range of floats. You should leave this as ``True``
506
+ unless the ``obs`` sequence is very small.
507
+
508
+ EXAMPLES::
509
+
510
+ sage: m = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]],
511
+ ....: [[0.1,0.9],[0.5,0.5]],
512
+ ....: [.2,.8])
513
+ sage: m.log_likelihood([0, 1, 0, 1, 1, 0, 1, 0, 0, 0])
514
+ -7.3301308009370825
515
+ sage: m.log_likelihood([0, 1, 0, 1, 1, 0, 1, 0, 0, 0], scale=False)
516
+ -7.330130800937082
517
+ sage: m.log_likelihood([])
518
+ 0.0
519
+
520
+ sage: m = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]],
521
+ ....: [[0.1,0.9],[0.5,0.5]],
522
+ ....: [.2,.8], ['happy','sad'])
523
+ sage: m.log_likelihood(['happy','happy'])
524
+ -1.6565295199679506
525
+ sage: m.log_likelihood(['happy','sad'])
526
+ -1.4731602941415523
527
+
528
+ Overflow from not using the scale option::
529
+
530
+ sage: m = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]],
531
+ ....: [[0.1,0.9],[0.5,0.5]],
532
+ ....: [.2,.8])
533
+ sage: m.log_likelihood([0,1]*1000, scale=True)
534
+ -1433.820666652728
535
+ sage: m.log_likelihood([0,1]*1000, scale=False)
536
+ -inf
537
+ """
538
+ if len(obs) == 0:
539
+ return 0.0
540
+ if self._emission_symbols is not None:
541
+ obs = self._emission_symbols_to_IntList(obs)
542
+ if not isinstance(obs, IntList):
543
+ obs = IntList(obs)
544
+ if scale:
545
+ return self._forward_scale(obs)
546
+ else:
547
+ return self._forward(obs)
548
+
549
+ def _forward(self, IntList obs):
550
+ r"""
551
+ Memory-efficient implementation of the forward algorithm, without
552
+ scaling.
553
+
554
+ INPUT:
555
+
556
+ - ``obs`` -- integer list of observation states
557
+
558
+ OUTPUT: ``float`` -- the log of the probability that the model produced
559
+ this sequence
560
+
561
+ EXAMPLES::
562
+
563
+ sage: m = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]], [[0.1,0.9],[0.5,0.5]], [.2,.8])
564
+ sage: m._forward(stats.IntList([0,1]*10))
565
+ -14.378663512219456
566
+
567
+ The forward algorithm computes the log likelihood::
568
+
569
+ sage: m.log_likelihood(stats.IntList([0,1]*10), scale=False)
570
+ -14.378663512219456
571
+
572
+ But numerical overflow will happen (without scaling) for long sequences::
573
+
574
+ sage: m._forward(stats.IntList([0,1]*1000))
575
+ -inf
576
+ """
577
+ if obs.max() > self.N or obs.min() < 0:
578
+ raise ValueError("invalid observation sequence, since it includes unknown states")
579
+
580
+ cdef Py_ssize_t i, j, t, T = len(obs)
581
+
582
+ cdef TimeSeries alpha = TimeSeries(self.N), \
583
+ alpha2 = TimeSeries(self.N)
584
+
585
+ # Initialization
586
+ for i in range(self.N):
587
+ alpha[i] = self.pi[i] * self.B[i*self.n_out + obs._values[0]]
588
+ alpha[i] = self.pi[i] * self.B[i*self.n_out + obs._values[0]]
589
+
590
+ # Induction
591
+ cdef double s
592
+ for t in range(1, T):
593
+ for j in range(self.N):
594
+ s = 0
595
+ for i in range(self.N):
596
+ s += alpha._values[i] * self.A._values[i*self.N + j]
597
+ alpha2._values[j] = s * self.B._values[j*self.n_out+obs._values[t]]
598
+ for j in range(self.N):
599
+ alpha._values[j] = alpha2._values[j]
600
+
601
+ # Termination
602
+ return log(alpha.sum())
603
+
604
+ def _forward_scale(self, IntList obs):
605
+ r"""
606
+ Memory-efficient implementation of the forward algorithm, with scaling.
607
+
608
+ INPUT:
609
+
610
+ - ``obs`` -- integer list of observation states
611
+
612
+ OUTPUT: ``float`` -- the log of the probability that the model produced
613
+ this sequence
614
+
615
+ EXAMPLES::
616
+
617
+ sage: m = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]], [[0.1,0.9],[0.5,0.5]], [.2,.8])
618
+ sage: m._forward_scale(stats.IntList([0,1]*10))
619
+ -14.378663512219454
620
+
621
+ The forward algorithm computes the log likelihood::
622
+
623
+ sage: m.log_likelihood(stats.IntList([0,1]*10))
624
+ -14.378663512219454
625
+
626
+ Note that the scale algorithm ensures that numerical overflow
627
+ won't happen for long sequences like it does with the forward
628
+ non-scaled algorithm::
629
+
630
+ sage: m._forward_scale(stats.IntList([0,1]*1000))
631
+ -1433.820666652728
632
+ sage: m._forward(stats.IntList([0,1]*1000))
633
+ -inf
634
+
635
+ A random sequence produced by the model is more likely::
636
+
637
+ sage: set_random_seed(0); v = m.sample(1000)
638
+ sage: m._forward_scale(v)
639
+ -686.8753189365056
640
+ """
641
+ # This is just like self._forward(obs) above, except at every step of the
642
+ # algorithm, we rescale the vector alpha so that the sum of
643
+ # the entries in alpha is 1. Then, at the end of the
644
+ # algorithm, the sum of probabilities (alpha.sum()) is of
645
+ # course just 1. However, the true probability that we want
646
+ # is the product of the numbers that we divided by when
647
+ # rescaling, since at each step of the iteration the next term
648
+ # depends linearly on the previous one. Instead of returning
649
+ # the product, we return the sum of the logs, which avoid
650
+ # numerical error.
651
+ cdef Py_ssize_t i, j, t, T = len(obs)
652
+
653
+ # The running some of the log probabilities
654
+ cdef double log_probability = 0, sum, a
655
+
656
+ cdef TimeSeries alpha = TimeSeries(self.N), \
657
+ alpha2 = TimeSeries(self.N)
658
+
659
+ # Initialization
660
+ sum = 0
661
+ for i in range(self.N):
662
+ a = self.pi[i] * self.B[i*self.n_out + obs._values[0]]
663
+ alpha[i] = a
664
+ sum += a
665
+
666
+ log_probability = log(sum)
667
+ alpha.rescale(1/sum)
668
+
669
+ # Induction
670
+ # The code below is just an optimized version of:
671
+ # alpha = (alpha * A).pairwise_product(B[O[t+1]])
672
+ # alpha = alpha.scale(1/alpha.sum())
673
+ # along with keeping track of the log of the scaling factor.
674
+ cdef double s
675
+ for t in range(1, T):
676
+ sum = 0
677
+ for j in range(self.N):
678
+ s = 0
679
+ for i in range(self.N):
680
+ s += alpha._values[i] * self.A._values[i*self.N + j]
681
+ a = s * self.B._values[j*self.n_out+obs._values[t]]
682
+ alpha2._values[j] = a
683
+ sum += a
684
+
685
+ log_probability += log(sum)
686
+ for j in range(self.N):
687
+ alpha._values[j] = alpha2._values[j] / sum
688
+
689
+ # Termination
690
+ return log_probability
691
+
692
+ def generate_sequence(self, Py_ssize_t length, starting_state=None):
693
+ r"""
694
+ Return a sample of the given length from this HMM.
695
+
696
+ INPUT:
697
+
698
+ - ``length`` -- positive integer
699
+ - ``starting_state`` -- integer (or ``None``); if specified, generate a
700
+ sequence using this model starting with the given state instead of
701
+ the initial probabilities to determine the starting state
702
+
703
+ OUTPUT:
704
+
705
+ - an :class:`IntList` or list of emission symbols
706
+ - :class:`IntList` of the actual states the model was in when
707
+ emitting the corresponding symbols
708
+
709
+ EXAMPLES:
710
+
711
+ In this example, the emission symbols are not set::
712
+
713
+ sage: set_random_seed(0)
714
+ sage: a = hmm.DiscreteHiddenMarkovModel([[0.1,0.9],[0.1,0.9]],
715
+ ....: [[1,0],[0,1]],
716
+ ....: [0,1])
717
+ sage: a.generate_sequence(5)
718
+ ([1, 0, 1, 1, 1], [1, 0, 1, 1, 1])
719
+ sage: list(a.generate_sequence(1000)[0]).count(0)
720
+ 90
721
+
722
+ Here the emission symbols are set::
723
+
724
+ sage: set_random_seed(0)
725
+ sage: a = hmm.DiscreteHiddenMarkovModel([[0.5,0.5],[0.1,0.9]],
726
+ ....: [[1,0],[0,1]],
727
+ ....: [0,1], ['up', 'down'])
728
+ sage: a.generate_sequence(5)
729
+ (['down', 'up', 'down', 'down', 'down'], [1, 0, 1, 1, 1])
730
+
731
+ Specify the starting state::
732
+
733
+ sage: set_random_seed(0); a.generate_sequence(5, starting_state=0)
734
+ (['up', 'up', 'down', 'down', 'down'], [0, 0, 1, 1, 1])
735
+ """
736
+ if length < 0:
737
+ raise ValueError("length must be nonnegative")
738
+
739
+ # Create Integer lists for states and observations
740
+ cdef IntList states = IntList(length)
741
+ cdef IntList obs = IntList(length)
742
+ if length == 0:
743
+ # A special case
744
+ if self._emission_symbols is None:
745
+ return states, obs
746
+ else:
747
+ return states, []
748
+
749
+ # Setup variables, including random state.
750
+ cdef Py_ssize_t i, j
751
+ cdef randstate rstate = current_randstate()
752
+ cdef int q = 0
753
+ cdef double r, accum
754
+ r = rstate.c_rand_double()
755
+
756
+ # Now choose random variables from our discrete distribution.
757
+
758
+ # This standard naive algorithm has complexity that is linear
759
+ # in the number of states. It might be possible to replace it
760
+ # by something that is more efficient. However, make sure to
761
+ # refactor this code into distribution.pyx before doing so.
762
+ # Note that state switching involves the same algorithm
763
+ # (below). Use GSL as described here to make this O(1):
764
+ # http://www.gnu.org/software/gsl/manual/html_node/General-Discrete-Distributions.html
765
+
766
+ # Choose initial state:
767
+ if starting_state is None:
768
+ accum = 0
769
+ for i in range(self.N):
770
+ if r < self.pi._values[i] + accum:
771
+ q = i
772
+ else:
773
+ accum += self.pi._values[i]
774
+ else:
775
+ q = starting_state
776
+ if q < 0 or q >= self.N:
777
+ raise ValueError("starting state must be between 0 and %s" % (self.N-1))
778
+
779
+ states._values[0] = q
780
+ # Generate a symbol from state q
781
+ obs._values[0] = self._gen_symbol(q, rstate.c_rand_double())
782
+
783
+ cdef double* row
784
+ cdef int O
785
+ sig_on()
786
+ for i in range(1, length):
787
+ # Choose next state
788
+ accum = 0
789
+ row = self.A._values + q*self.N
790
+ r = rstate.c_rand_double()
791
+ for j in range(self.N):
792
+ if r < row[j] + accum:
793
+ q = j
794
+ break
795
+ else:
796
+ accum += row[j]
797
+ states._values[i] = q
798
+ # Generate symbol from this new state q
799
+ obs._values[i] = self._gen_symbol(q, rstate.c_rand_double())
800
+ sig_off()
801
+
802
+ if self._emission_symbols is None:
803
+ # No emission symbol mapping
804
+ return obs, states
805
+ else:
806
+ # Emission symbol mapping, so change our intlist into a list of symbols
807
+ return self._IntList_to_emission_symbols(obs), states
808
+
809
+ cdef int _gen_symbol(self, int q, double r) noexcept:
810
+ r"""
811
+ Generate a symbol in state q using the randomly chosen
812
+ floating point number r, which should be between 0 and 1.
813
+
814
+ INPUT:
815
+
816
+ - ``q`` -- nonnegative integer, which specifies a state
817
+ - ``r`` -- a real number between 0 and 1
818
+
819
+ OUTPUT: a nonnegative int
820
+
821
+ EXAMPLES::
822
+
823
+ sage: m = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]], [[0.1,0.9],[0.9,0.1]], [.2,.8])
824
+ sage: set_random_seed(0)
825
+ sage: m.generate_sequence(10) # indirect test
826
+ ([0, 1, 0, 0, 0, 0, 1, 0, 1, 1], [1, 0, 1, 1, 1, 1, 0, 0, 0, 0])
827
+ """
828
+ cdef Py_ssize_t j
829
+ cdef double a, accum = 0
830
+ # See the comments above about switching to GSL for this; also note
831
+ # that this should get factored out into a call to something
832
+ # defined in distributions.pyx.
833
+ for j in range(self.n_out):
834
+ a = self.B._values[q*self.n_out + j]
835
+ if r < a + accum:
836
+ return j
837
+ else:
838
+ accum += a
839
+ # None of the values was selected: shouldn't this only happen if the
840
+ # distribution is invalid? Anyway, this will get factored out.
841
+ return self.n_out - 1
842
+
843
+ def viterbi(self, obs, log_scale=True):
844
+ r"""
845
+ Determine "the" hidden sequence of states that is most likely
846
+ to produce the given sequence seq of observations, along with
847
+ the probability that this hidden sequence actually produced
848
+ the observation.
849
+
850
+ INPUT:
851
+
852
+ - ``seq`` -- sequence of emitted ints or symbols
853
+
854
+ - ``log_scale`` -- boolean (default: ``True``); whether to scale the
855
+ sequence in order to avoid numerical overflow
856
+
857
+ OUTPUT:
858
+
859
+ - ``list`` -- "the" most probable sequence of hidden states, i.e.,
860
+ the Viterbi path
861
+
862
+ - ``float`` -- log of probability that the observed sequence
863
+ was produced by the Viterbi sequence of states
864
+
865
+ EXAMPLES::
866
+
867
+ sage: a = hmm.DiscreteHiddenMarkovModel([[0.1,0.9],[0.1,0.9]],
868
+ ....: [[0.9,0.1],[0.1,0.9]],
869
+ ....: [0.5,0.5])
870
+ sage: a.viterbi([1,0,0,1,0,0,1,1])
871
+ ([1, 0, 0, 1, ..., 0, 1, 1], -11.06245322477221...)
872
+
873
+ We predict the state sequence when the emissions are 3/4 and 'abc'.::
874
+
875
+ sage: a = hmm.DiscreteHiddenMarkovModel([[0.1,0.9],[0.1,0.9]],
876
+ ....: [[0.9,0.1],[0.1,0.9]],
877
+ ....: [0.5,0.5], [3/4, 'abc'])
878
+
879
+ Note that state 0 is common below, despite the model trying hard to
880
+ switch to state 1::
881
+
882
+ sage: a.viterbi([3/4, 'abc', 'abc'] + [3/4]*10)
883
+ ([0, 1, 1, 0, 0 ... 0, 0, 0, 0, 0], -25.299405845367794)
884
+ """
885
+ if self._emission_symbols is not None:
886
+ obs = self._emission_symbols_to_IntList(obs)
887
+ elif not isinstance(obs, IntList):
888
+ obs = IntList(obs)
889
+ if log_scale:
890
+ return self._viterbi_scale(obs)
891
+ else:
892
+ return self._viterbi(obs)
893
+
894
+ cpdef _viterbi(self, IntList obs):
895
+ r"""
896
+ Used internally to compute the viterbi path, without
897
+ rescaling. This can be useful for short sequences.
898
+
899
+ INPUT:
900
+
901
+ - ``obs`` -- IntList
902
+
903
+ OUTPUT:
904
+
905
+ - IntList (most likely state sequence)
906
+
907
+ - log of probability that the observed sequence was
908
+ produced by the Viterbi sequence of states.
909
+
910
+ EXAMPLES::
911
+
912
+ sage: m = hmm.DiscreteHiddenMarkovModel([[0.1,0.9],[0.9,0.1]], [[1,0],[0,1]], [.2,.8])
913
+ sage: m._viterbi(stats.IntList([1]*5))
914
+ ([1, 1, 1, 1, 1], -9.433483923290392)
915
+ sage: m._viterbi(stats.IntList([0]*5))
916
+ ([0, 0, 0, 0, 0], -10.819778284410283)
917
+
918
+ Long sequences will overflow::
919
+
920
+ sage: m._viterbi(stats.IntList([0]*1000))
921
+ ([0, 0, 0, 0, 0 ... 0, 0, 0, 0, 0], -inf)
922
+ """
923
+ cdef Py_ssize_t t, T = obs._length
924
+ cdef IntList state_sequence = IntList(T)
925
+ if T == 0:
926
+ return state_sequence, 0.0
927
+
928
+ cdef int i, j, N = self.N
929
+
930
+ # delta[i] is the maximum of the probabilities over all
931
+ # paths ending in state i.
932
+ cdef TimeSeries delta = TimeSeries(N), delta_prev = TimeSeries(N)
933
+
934
+ # We view psi as an N x T matrix of ints. The quantity
935
+ # psi[N*t + j]
936
+ # is a most probable hidden state at time t-1, given
937
+ # that j is a most probable state at time j.
938
+ cdef IntList psi = IntList(N * T) # initialized to 0 by default
939
+
940
+ # Initialization:
941
+ for i in range(N):
942
+ delta._values[i] = self.pi._values[i] * self.B._values[self.n_out*i + obs._values[0]]
943
+
944
+ # Recursion:
945
+ cdef double mx, tmp
946
+ cdef int index
947
+ for t in range(1, T):
948
+ delta_prev, delta = delta, delta_prev
949
+ for j in range(N):
950
+ # delta_t[j] = max_i(delta_{t-1}(i) a_{i,j}) * b_j(obs[t])
951
+ mx = -1
952
+ index = -1
953
+ for i in range(N):
954
+ tmp = delta_prev._values[i]*self.A._values[i*N+j]
955
+ if tmp > mx:
956
+ mx = tmp
957
+ index = i
958
+ delta._values[j] = mx * self.B._values[self.n_out*j + obs._values[t]]
959
+ psi._values[N*t + j] = index
960
+
961
+ # Termination:
962
+ mx, index = delta.max(index=True)
963
+
964
+ # Path (state sequence) backtracking:
965
+ state_sequence._values[T-1] = index
966
+ t = T-2
967
+ while t >= 0:
968
+ state_sequence._values[t] = psi._values[N*(t+1) + state_sequence._values[t+1]]
969
+ t -= 1
970
+
971
+ return state_sequence, log(mx)
972
+
973
+ cpdef _viterbi_scale(self, IntList obs):
974
+ r"""
975
+ Used internally to compute the viterbi path with rescaling.
976
+
977
+ INPUT:
978
+
979
+ - ``obs`` -- IntList
980
+
981
+ OUTPUT:
982
+
983
+ - IntList (most likely state sequence)
984
+
985
+ - log of probability that the observed sequence was
986
+ produced by the Viterbi sequence of states.
987
+
988
+ EXAMPLES::
989
+
990
+ sage: m = hmm.DiscreteHiddenMarkovModel([[0.1,0.9],[0.9,0.1]], [[.5,.5],[0,1]], [.2,.8])
991
+ sage: m._viterbi_scale(stats.IntList([1]*10))
992
+ ([1, 0, 1, 0, 1, 0, 1, 0, 1, 0], -4.637124095034373)
993
+
994
+ Long sequences should not overflow::
995
+
996
+ sage: m._viterbi_scale(stats.IntList([1]*1000))
997
+ ([1, 0, 1, 0, 1 ... 0, 1, 0, 1, 0], -452.05188897345...)
998
+ """
999
+ # The algorithm is the same as _viterbi above, except
1000
+ # we take the logarithms of everything first, and add
1001
+ # instead of multiply.
1002
+ cdef Py_ssize_t t, T = obs._length
1003
+ cdef IntList state_sequence = IntList(T)
1004
+ if T == 0:
1005
+ return state_sequence, 0.0
1006
+ cdef int i, j, N = self.N
1007
+
1008
+ # delta[i] is the maximum of the probabilities over all
1009
+ # paths ending in state i.
1010
+ cdef TimeSeries delta = TimeSeries(N), delta_prev = TimeSeries(N)
1011
+
1012
+ # We view psi as an N x T matrix of ints. The quantity
1013
+ # psi[N*t + j]
1014
+ # is a most probable hidden state at time t-1, given
1015
+ # that j is a most probable state at time j.
1016
+ cdef IntList psi = IntList(N * T) # initialized to 0 by default
1017
+
1018
+ # Log Preprocessing
1019
+ cdef TimeSeries A = self.A.log()
1020
+ cdef TimeSeries B = self.B.log()
1021
+ cdef TimeSeries pi = self.pi.log()
1022
+
1023
+ # Initialization:
1024
+ for i in range(N):
1025
+ delta._values[i] = pi._values[i] + B._values[self.n_out*i + obs._values[0]]
1026
+
1027
+ # Recursion:
1028
+ cdef double mx, tmp, minus_inf = float('-inf')
1029
+ cdef int index
1030
+
1031
+ for t in range(1, T):
1032
+ delta_prev, delta = delta, delta_prev
1033
+ for j in range(N):
1034
+ # delta_t[j] = max_i(delta_{t-1}(i) a_{i,j}) * b_j(obs[t])
1035
+ mx = minus_inf
1036
+ index = -1
1037
+ for i in range(N):
1038
+ tmp = delta_prev._values[i] + A._values[i*N+j]
1039
+ if tmp > mx:
1040
+ mx = tmp
1041
+ index = i
1042
+ delta._values[j] = mx + B._values[self.n_out*j + obs._values[t]]
1043
+ psi._values[N*t + j] = index
1044
+
1045
+ # Termination:
1046
+ mx, index = delta.max(index=True)
1047
+
1048
+ # Path (state sequence) backtracking:
1049
+ state_sequence._values[T-1] = index
1050
+ t = T-2
1051
+ while t >= 0:
1052
+ state_sequence._values[t] = psi._values[N*(t+1) + state_sequence._values[t+1]]
1053
+ t -= 1
1054
+
1055
+ return state_sequence, mx
1056
+
1057
+ cdef TimeSeries _backward_scale_all(self, IntList obs, TimeSeries scale):
1058
+ r"""
1059
+ Return the scaled matrix of values `\beta_t(i)` that appear in
1060
+ the backtracking algorithm. This function is used internally
1061
+ by the Baum-Welch algorithm.
1062
+
1063
+ The matrix is stored as a TimeSeries T, such that
1064
+ `\beta_t(i) = T[t*N + i]` where N is the number of states of
1065
+ the Hidden Markov Model.
1066
+
1067
+ The quantity beta_t(i) is the probability of observing the
1068
+ sequence obs[t+1:] assuming that the model is in state i at
1069
+ time t.
1070
+
1071
+ INPUT:
1072
+
1073
+ - ``obs`` -- IntList
1074
+ - ``scale`` -- series that is *changed* in place, so that
1075
+ after calling this function, scale[t] is value that is
1076
+ used to scale each of the `\beta_t(i)`.
1077
+
1078
+ OUTPUT:
1079
+
1080
+ - a TimeSeries of values beta_t(i).
1081
+ - the input object scale is modified
1082
+ """
1083
+ cdef Py_ssize_t t, T = obs._length
1084
+ cdef int N = self.N, i, j
1085
+ cdef double s
1086
+ cdef TimeSeries beta = TimeSeries(N*T, initialize=False)
1087
+
1088
+ # 1. Initialization
1089
+ for i in range(N):
1090
+ beta._values[(T-1)*N + i] = 1/scale._values[T-1]
1091
+
1092
+ # 2. Induction
1093
+ t = T-2
1094
+ while t >= 0:
1095
+ for i in range(N):
1096
+ s = 0
1097
+ for j in range(N):
1098
+ s += self.A._values[i*N+j] * \
1099
+ self.B._values[j*self.n_out+obs._values[t+1]] * beta._values[(t+1)*N+j]
1100
+ beta._values[t*N + i] = s/scale._values[t]
1101
+ t -= 1
1102
+ return beta
1103
+
1104
+ cdef _forward_scale_all(self, IntList obs):
1105
+ r"""
1106
+ Return scaled values alpha_t(i), the sequence of scalings, and
1107
+ the log probability.
1108
+
1109
+ INPUT:
1110
+
1111
+ - ``obs`` -- IntList
1112
+
1113
+ OUTPUT:
1114
+
1115
+ - TimeSeries alpha with alpha_t(i) = alpha[t*N + i]
1116
+ - TimeSeries scale with scale[t] the scaling at step t
1117
+ - ``float`` -- log_probability of the observation sequence
1118
+ being produced by the model
1119
+ """
1120
+ cdef Py_ssize_t i, j, t, T = len(obs)
1121
+ cdef int N = self.N
1122
+
1123
+ # The running some of the log probabilities
1124
+ cdef double log_probability = 0, sum, a
1125
+
1126
+ cdef TimeSeries alpha = TimeSeries(N*T, initialize=False)
1127
+ cdef TimeSeries scale = TimeSeries(T, initialize=False)
1128
+
1129
+ # Initialization
1130
+ sum = 0
1131
+ for i in range(self.N):
1132
+ a = self.pi._values[i] * self.B._values[i*self.n_out + obs._values[0]]
1133
+ alpha._values[0*N + i] = a
1134
+ sum += a
1135
+
1136
+ scale._values[0] = sum
1137
+ log_probability = log(sum)
1138
+ for i in range(self.N):
1139
+ alpha._values[0*N + i] /= sum
1140
+
1141
+ # Induction
1142
+ # The code below is just an optimized version of:
1143
+ # alpha = (alpha * A).pairwise_product(B[O[t+1]])
1144
+ # alpha = alpha.scale(1/alpha.sum())
1145
+ # along with keeping track of the log of the scaling factor.
1146
+ cdef double s
1147
+ for t in range(1,T):
1148
+ sum = 0
1149
+ for j in range(N):
1150
+ s = 0
1151
+ for i in range(N):
1152
+ s += alpha._values[(t-1)*N + i] * self.A._values[i*N + j]
1153
+ a = s * self.B._values[j*self.n_out + obs._values[t]]
1154
+ alpha._values[t*N + j] = a
1155
+ sum += a
1156
+
1157
+ log_probability += log(sum)
1158
+ scale._values[t] = sum
1159
+ for j in range(self.N):
1160
+ alpha._values[t*N + j] /= sum
1161
+
1162
+ # Termination
1163
+ return alpha, scale, log_probability
1164
+
1165
+ cdef TimeSeries _baum_welch_xi(self, TimeSeries alpha, TimeSeries beta, IntList obs):
1166
+ r"""
1167
+ Used internally to compute the scaled quantity xi_t(i,j)
1168
+ appearing in the Baum-Welch reestimation algorithm.
1169
+
1170
+ INPUT:
1171
+
1172
+ - ``alpha`` -- TimeSeries as output by the scaled forward algorithm
1173
+ - ``beta`` -- TimeSeries as output by the scaled backward algorithm
1174
+ - ``obs `` -- IntList of observations
1175
+
1176
+ OUTPUT:
1177
+
1178
+ - TimeSeries xi such that xi[t*N*N + i*N + j] = xi_t(i,j).
1179
+ """
1180
+ cdef int i, j, N = self.N
1181
+ cdef double sum
1182
+ cdef Py_ssize_t t, T = alpha._length//N
1183
+ cdef TimeSeries xi = TimeSeries(T*N*N, initialize=False)
1184
+ sig_on()
1185
+ for t in range(T-1):
1186
+ sum = 0.0
1187
+ for i in range(N):
1188
+ for j in range(N):
1189
+ xi._values[t*N*N + i*N + j] = alpha._values[t*N + i]*beta._values[(t+1)*N + j]*\
1190
+ self.A._values[i*N + j] * self.B._values[j*self.n_out + obs._values[t+1]]
1191
+ sum += xi._values[t*N*N + i*N + j]
1192
+ for i in range(N):
1193
+ for j in range(N):
1194
+ xi._values[t*N*N + i*N + j] /= sum
1195
+ sig_off()
1196
+ return xi
1197
+
1198
+ def baum_welch(self, obs, int max_iter=100, double log_likelihood_cutoff=1e-4, bint fix_emissions=False):
1199
+ r"""
1200
+ Given an observation sequence obs, improve this HMM using the
1201
+ Baum-Welch algorithm to increase the probability of observing obs.
1202
+
1203
+ INPUT:
1204
+
1205
+ - ``obs`` -- list of emissions
1206
+
1207
+ - ``max_iter`` -- integer (default: 100); maximum number
1208
+ of Baum-Welch steps to take
1209
+
1210
+ - ``log_likelihood_cutoff`` -- positive float (default: 1e-4);
1211
+ the minimal improvement in likelihood with respect to
1212
+ the last iteration required to continue. Relative value
1213
+ to log likelihood.
1214
+
1215
+ - ``fix_emissions`` -- boolean (default: ``False``); if ``True``, do
1216
+ not change emissions when updating
1217
+
1218
+ OUTPUT:
1219
+
1220
+ changes the model in place, and returns the log
1221
+ likelihood and number of iterations.
1222
+
1223
+ EXAMPLES::
1224
+
1225
+ sage: m = hmm.DiscreteHiddenMarkovModel([[0.1,0.9],[0.9,0.1]],
1226
+ ....: [[.5,.5],[0,1]],
1227
+ ....: [.2,.8])
1228
+ sage: m.baum_welch([1,0]*20, log_likelihood_cutoff=0)
1229
+ (0.0, 4)
1230
+ sage: m # rel tol 1e-14
1231
+ Discrete Hidden Markov Model with 2 States and 2 Emissions
1232
+ Transition matrix:
1233
+ [1.3515269707707603e-51 1.0]
1234
+ [ 1.0 0.0]
1235
+ Emission matrix:
1236
+ [ 1.0 6.462537138850569e-52]
1237
+ [ 0.0 1.0]
1238
+ Initial probabilities: [0.0000, 1.0000]
1239
+
1240
+ The following illustrates how Baum-Welch is only a local
1241
+ optimizer, i.e., the above model is far more likely to produce
1242
+ the sequence [1,0]*20 than the one we get below::
1243
+
1244
+ sage: m = hmm.DiscreteHiddenMarkovModel([[0.5,0.5],[0.5,0.5]],
1245
+ ....: [[.5,.5],[.5,.5]],
1246
+ ....: [.5,.5])
1247
+ sage: m.baum_welch([1,0]*20, log_likelihood_cutoff=0)
1248
+ (-27.725887222397784, 1)
1249
+ sage: m
1250
+ Discrete Hidden Markov Model with 2 States and 2 Emissions
1251
+ Transition matrix:
1252
+ [0.5 0.5]
1253
+ [0.5 0.5]
1254
+ Emission matrix:
1255
+ [0.5 0.5]
1256
+ [0.5 0.5]
1257
+ Initial probabilities: [0.5000, 0.5000]
1258
+
1259
+ We illustrate fixing emissions::
1260
+
1261
+ sage: m = hmm.DiscreteHiddenMarkovModel([[0.1,0.9],[0.9,0.1]],
1262
+ ....: [[.5,.5],[.2,.8]],
1263
+ ....: [.2,.8])
1264
+ sage: set_random_seed(0); v = m.sample(100)
1265
+ sage: m.baum_welch(v,fix_emissions=True)
1266
+ (-66.98630856918774, 100)
1267
+ sage: m.emission_matrix()
1268
+ [0.5 0.5]
1269
+ [0.2 0.8]
1270
+ sage: m = hmm.DiscreteHiddenMarkovModel([[0.1,0.9],[0.9,0.1]],
1271
+ ....: [[.5,.5],[.2,.8]],
1272
+ ....: [.2,.8])
1273
+ sage: m.baum_welch(v)
1274
+ (-66.782360659293..., 100)
1275
+ sage: m.emission_matrix() # rel tol 1e-14
1276
+ [ 0.5303085748626447 0.46969142513735535]
1277
+ [ 0.2909775550173978 0.7090224449826023]
1278
+ """
1279
+ if self._emission_symbols is not None:
1280
+ obs = self._emission_symbols_to_IntList(obs)
1281
+ elif not isinstance(obs, IntList):
1282
+ obs = IntList(obs)
1283
+ cdef IntList _obs = obs
1284
+ cdef TimeSeries alpha, beta, scale, gamma, xi
1285
+ cdef double log_probability, log_probability_prev, delta
1286
+ cdef int i, j, k, N, n_iterations
1287
+ cdef Py_ssize_t t, T
1288
+ cdef double denominator_A, numerator_A, denominator_B, numerator_B
1289
+
1290
+ # Initialization
1291
+ alpha, scale, log_probability = self._forward_scale_all(_obs)
1292
+ beta = self._backward_scale_all(_obs, scale)
1293
+ gamma = self._baum_welch_gamma(alpha, beta)
1294
+ xi = self._baum_welch_xi(alpha, beta, _obs)
1295
+ log_probability_prev = log_probability
1296
+ N = self.N
1297
+ n_iterations = 0
1298
+ T = len(_obs)
1299
+
1300
+ # Re-estimation
1301
+ while True:
1302
+
1303
+ # Reestimate frequency of state i in time t=0
1304
+ for i in range(N):
1305
+ self.pi._values[i] = gamma._values[0*N+i]
1306
+
1307
+ # Reestimate transition matrix and emissions probability in
1308
+ # each state.
1309
+ for i in range(N):
1310
+ denominator_A = 0.0
1311
+ for t in range(T-1):
1312
+ denominator_A += gamma._values[t*N+i]
1313
+ for j in range(N):
1314
+ numerator_A = 0.0
1315
+ for t in range(T-1):
1316
+ numerator_A += xi._values[t*N*N+i*N+j]
1317
+ self.A._values[i*N+j] = numerator_A / denominator_A
1318
+
1319
+ if not fix_emissions:
1320
+ denominator_B = denominator_A + gamma._values[(T-1)*N + i]
1321
+ for k in range(self.n_out):
1322
+ numerator_B = 0.0
1323
+ for t in range(T):
1324
+ if _obs._values[t] == k:
1325
+ numerator_B += gamma._values[t*N + i]
1326
+ self.B._values[i*self.n_out + k] = numerator_B / denominator_B
1327
+
1328
+ # Initialization
1329
+ alpha, scale, log_probability = self._forward_scale_all(_obs)
1330
+ beta = self._backward_scale_all(_obs, scale)
1331
+ gamma = self._baum_welch_gamma(alpha, beta)
1332
+ xi = self._baum_welch_xi(alpha, beta, _obs)
1333
+
1334
+ # Compute the difference between the log probability of
1335
+ # two iterations.
1336
+ delta = log_probability - log_probability_prev
1337
+ log_probability_prev = log_probability
1338
+ n_iterations += 1
1339
+
1340
+ # If the log probability does not change by more than
1341
+ # delta, then terminate
1342
+ if delta <= log_likelihood_cutoff or n_iterations >= max_iter:
1343
+ break
1344
+
1345
+ return log_probability, n_iterations
1346
+
1347
+
1348
+ # Keep this -- it's for backwards compatibility with the GHMM based implementation
1349
+ def unpickle_discrete_hmm_v0(A, B, pi, emission_symbols, name):
1350
+ r"""
1351
+ TESTS::
1352
+
1353
+ sage: m = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]], [[0.0,1.0],[0.5,0.5]], [1,0])
1354
+ sage: sage.stats.hmm.hmm.unpickle_discrete_hmm_v0(m.transition_matrix(), m.emission_matrix(), m.initial_probabilities(), ['a','b'], 'test model')
1355
+ Discrete Hidden Markov Model with 2 States and 2 Emissions...
1356
+ """
1357
+ return DiscreteHiddenMarkovModel(A, B, pi, emission_symbols, normalize=False)
1358
+
1359
+
1360
+ def unpickle_discrete_hmm_v1(A, B, pi, n_out, emission_symbols, emission_symbols_dict):
1361
+ r"""
1362
+ Return a :class:`DiscreteHiddenMarkovModel`, restored from the arguments.
1363
+
1364
+ This function is used internally for unpickling.
1365
+
1366
+ TESTS::
1367
+
1368
+ sage: m = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]], [[0.0,1.0],[0.5,0.5]], [1,0],['a','b'])
1369
+ sage: m2 = loads(dumps(m)) # indirect doctest
1370
+ sage: m2 == m
1371
+ True
1372
+
1373
+ Test that :issue:`15711` has been resolved::
1374
+
1375
+ sage: str(m2) == str(m)
1376
+ True
1377
+ sage: m2.log_likelihood('baa'*2) == m.log_likelihood('baa'*2)
1378
+ True
1379
+ """
1380
+ cdef DiscreteHiddenMarkovModel m = DiscreteHiddenMarkovModel.__new__(DiscreteHiddenMarkovModel)
1381
+ m.A = A
1382
+ m.B = B
1383
+ m.pi = pi
1384
+ m.N = len(pi)
1385
+ m.n_out = n_out
1386
+ m._emission_symbols = emission_symbols
1387
+ m._emission_symbols_dict = emission_symbols_dict
1388
+ return m