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/matrix/special.py ADDED
@@ -0,0 +1,3666 @@
1
+ # sage_setup: distribution = sagemath-modules
2
+ """
3
+ Constructors for special matrices
4
+
5
+ This module gathers several constructors for special, commonly used or
6
+ interesting matrices. These can be reached through ``matrix.<tab>``.
7
+
8
+ For example, here is a circulant matrix of order five::
9
+
10
+ sage: matrix.circulant(SR.var('a b c d e')) # needs sage.symbolic
11
+ [a b c d e]
12
+ [e a b c d]
13
+ [d e a b c]
14
+ [c d e a b]
15
+ [b c d e a]
16
+
17
+ The following constructions are available:
18
+
19
+ .. csv-table::
20
+ :class: contentstable
21
+ :widths: 30
22
+ :delim: |
23
+
24
+ :meth:`~sage.matrix.special.block_diagonal_matrix`
25
+ :meth:`~sage.matrix.special.block_matrix`
26
+ :meth:`~sage.matrix.special.circulant`
27
+ :meth:`~sage.matrix.special.column_matrix`
28
+ :meth:`~sage.matrix.special.companion_matrix`
29
+ :meth:`~sage.matrix.special.diagonal_matrix`
30
+ :meth:`~sage.matrix.special.elementary_matrix`
31
+ :meth:`~sage.matrix.special.hankel`
32
+ :meth:`~sage.matrix.special.hilbert`
33
+ :meth:`~sage.matrix.special.identity_matrix`
34
+ :meth:`~sage.matrix.special.ith_to_zero_rotation_matrix`
35
+ :meth:`~sage.matrix.special.jordan_block`
36
+ :meth:`~sage.matrix.special.lehmer`
37
+ :meth:`~sage.matrix.special.ones_matrix`
38
+ :meth:`~sage.matrix.special.random_matrix`
39
+ :meth:`~sage.matrix.special.random_diagonalizable_matrix`
40
+ :meth:`~sage.matrix.special.random_echelonizable_matrix`
41
+ :meth:`~sage.matrix.special.random_rref_matrix`
42
+ :meth:`~sage.matrix.special.random_subspaces_matrix`
43
+ :meth:`~sage.matrix.special.random_unimodular_matrix`
44
+ :meth:`~sage.matrix.special.toeplitz`
45
+ :meth:`~sage.matrix.special.vandermonde`
46
+ :meth:`~sage.matrix.special.vector_on_axis_rotation_matrix`
47
+ :meth:`~sage.matrix.special.zero_matrix`
48
+
49
+ The Combinatorics module provides further matrix constructors, such as Hadamard
50
+ matrices and Latin squares. See:
51
+
52
+ - :mod:`sage.combinat.matrices.hadamard_matrix`
53
+ - :mod:`sage.combinat.matrices.latin`
54
+ """
55
+
56
+ # ****************************************************************************
57
+ # Copyright (C) 2005 William Stein <wstein@gmail.com>
58
+ #
59
+ # This program is free software: you can redistribute it and/or modify
60
+ # it under the terms of the GNU General Public License as published by
61
+ # the Free Software Foundation, either version 2 of the License, or
62
+ # (at your option) any later version.
63
+ # https://www.gnu.org/licenses/
64
+ # ****************************************************************************
65
+ from copy import copy
66
+
67
+ import sage.matrix.matrix_space as matrix_space
68
+ from sage.categories.rings import Rings
69
+ from sage.modules.free_module_element import vector
70
+ from sage.structure.element import Matrix, parent, RingElement
71
+ from sage.structure.sequence import Sequence
72
+ from sage.rings.integer_ring import ZZ
73
+ from sage.rings.rational_field import QQ
74
+ from sage.rings.integer import Integer
75
+ from sage.misc.misc_c import running_total
76
+ from sage.misc.prandom import randint, shuffle
77
+ from .constructor import matrix
78
+ import sage.categories.pushout
79
+
80
+
81
+ def matrix_method(func=None, name=None):
82
+ """
83
+ Allow a function to be tab-completed on the global matrix
84
+ constructor object.
85
+
86
+ INPUT:
87
+
88
+ - ``*function`` -- a single argument; the function that is being
89
+ decorated
90
+
91
+ - ``**kwds`` -- a single optional keyword argument
92
+ ``name=<string>``. The name of the corresponding method in the
93
+ global matrix constructor object. If not given, it is derived
94
+ from the function name.
95
+
96
+ EXAMPLES::
97
+
98
+ sage: from sage.matrix.constructor import matrix_method
99
+ sage: def foo_matrix(n): return matrix.diagonal(range(n))
100
+ sage: matrix_method(foo_matrix)
101
+ <function foo_matrix at ...>
102
+ sage: matrix.foo(5)
103
+ [0 0 0 0 0]
104
+ [0 1 0 0 0]
105
+ [0 0 2 0 0]
106
+ [0 0 0 3 0]
107
+ [0 0 0 0 4]
108
+ sage: matrix_method(foo_matrix, name='bar')
109
+ <function foo_matrix at ...>
110
+ sage: matrix.bar(3)
111
+ [0 0 0]
112
+ [0 1 0]
113
+ [0 0 2]
114
+ """
115
+ if func is not None:
116
+ if name is None:
117
+ name = func.__name__.replace('matrix', '').strip('_')
118
+ prefix = " This function is available as %s(...) and matrix.%s(...)." % (
119
+ func.__name__, name)
120
+ func.__doc__ = "%s\n\n%s" % (prefix, func.__doc__)
121
+ setattr(matrix, name, func)
122
+ return func
123
+ else:
124
+ return lambda func: matrix_method(func, name=name)
125
+
126
+
127
+ @matrix_method
128
+ def column_matrix(*args, **kwds):
129
+ r"""
130
+ Construct a matrix, and then swap rows for columns and columns for rows.
131
+
132
+ .. NOTE::
133
+
134
+ Linear algebra in Sage favors rows over columns. So,
135
+ generally, when creating a matrix, input vectors and lists are
136
+ treated as rows. This function is a convenience that turns
137
+ around this convention when creating a matrix. If you are not
138
+ familiar with the usual :func:`matrix`
139
+ constructor, you might want to consider it first.
140
+
141
+ INPUT:
142
+
143
+ Inputs are almost exactly the same as for the :func:`matrix`
144
+ constructor, which are documented there. But see
145
+ examples below for how dimensions are handled.
146
+
147
+ OUTPUT:
148
+
149
+ Output is exactly the transpose of what the :func:`matrix`
150
+ constructor would return. In other words, the
151
+ ``matrix`` constructor builds a matrix and then this function
152
+ exchanges rows for columns, and columns for rows.
153
+
154
+ EXAMPLES:
155
+
156
+ The most compelling use of this function is when you have a
157
+ collection of lists or vectors that you would like to become the
158
+ columns of a matrix. In almost any other situation, the
159
+ :func:`matrix` constructor can probably do the
160
+ job just as easily, or easier. ::
161
+
162
+ sage: col_1 = [1,2,3]
163
+ sage: col_2 = [4,5,6]
164
+ sage: column_matrix([col_1, col_2])
165
+ [1 4]
166
+ [2 5]
167
+ [3 6]
168
+
169
+ sage: v1 = vector(QQ, [10, 20])
170
+ sage: v2 = vector(QQ, [30, 40])
171
+ sage: column_matrix(QQ, [v1, v2])
172
+ [10 30]
173
+ [20 40]
174
+
175
+ If you only specify one dimension along with a flat list of entries,
176
+ then it will be the number of columns in the result (which is different
177
+ from the behavior of the ``matrix`` constructor). ::
178
+
179
+ sage: column_matrix(ZZ, 8, range(24))
180
+ [ 0 3 6 9 12 15 18 21]
181
+ [ 1 4 7 10 13 16 19 22]
182
+ [ 2 5 8 11 14 17 20 23]
183
+
184
+ And when you specify two dimensions, then they should be number of
185
+ columns first, then the number of rows, which is the reverse of how
186
+ they would be specified for the ``matrix`` constructor. ::
187
+
188
+ sage: column_matrix(QQ, 5, 3, range(15))
189
+ [ 0 3 6 9 12]
190
+ [ 1 4 7 10 13]
191
+ [ 2 5 8 11 14]
192
+
193
+ And a few unproductive, but illustrative, examples. ::
194
+
195
+ sage: A = matrix(ZZ, 3, 4, range(12))
196
+ sage: B = column_matrix(ZZ, 3, 4, range(12))
197
+ sage: A == B.transpose()
198
+ True
199
+
200
+ sage: A = matrix(QQ, 7, 12, range(84))
201
+ sage: A == column_matrix(A.columns())
202
+ True
203
+
204
+ sage: A = column_matrix(QQ, matrix(ZZ, 3, 2, range(6)) )
205
+ sage: A
206
+ [0 2 4]
207
+ [1 3 5]
208
+ sage: A.parent()
209
+ Full MatrixSpace of 2 by 3 dense matrices over Rational Field
210
+ """
211
+ return matrix(*args, **kwds).transpose()
212
+
213
+
214
+ @matrix_method
215
+ def random_matrix(ring, nrows, ncols=None, algorithm='randomize', implementation=None, *args, **kwds):
216
+ r"""
217
+ Return a random matrix with entries in a specified ring, and possibly with additional properties.
218
+
219
+ INPUT:
220
+
221
+ - ``ring`` -- base ring for entries of the matrix
222
+
223
+ - ``nrows`` -- integer; number of rows
224
+
225
+ - ``ncols`` -- (default: ``None``) number of columns. If ``None``
226
+ defaults to ``nrows``.
227
+
228
+ - ``algorithm`` -- (default: ``'randomize'``) determines what properties
229
+ the matrix will have. See examples below for possible additional
230
+ arguments.
231
+
232
+ - ``'randomize'`` -- create a matrix of random elements from the
233
+ base ring, possibly controlling the density of nonzero entries
234
+
235
+ - ``'echelon_form'`` -- creates a matrix in echelon form
236
+
237
+ - ``'echelonizable'`` -- creates a matrix that has a predictable
238
+ echelon form
239
+
240
+ - ``'subspaces'`` -- creates a matrix whose four subspaces, when
241
+ explored, have reasonably sized, integral valued, entries
242
+
243
+ - ``'unimodular'`` -- creates a matrix of determinant 1
244
+
245
+ - ``'diagonalizable'`` -- creates a diagonalizable matrix. if the
246
+ base ring is ``QQ`` creates a diagonalizable matrix whose eigenvectors,
247
+ if computed by hand, will have only integer entries. See the
248
+ documentation of :meth:`~sage.matrix.special.random_diagonalizable_matrix`
249
+ for more information
250
+
251
+ - ``implementation`` -- (``None`` or string or a matrix class) a possible
252
+ implementation. See the documentation of the constructor of
253
+ :class:`~sage.matrix.matrix_space.MatrixSpace`.
254
+
255
+ - ``*args, **kwds`` -- arguments and keywords to describe additional
256
+ properties. See more detailed documentation below
257
+
258
+ .. warning::
259
+
260
+ Matrices generated are not uniformly distributed. For unimodular
261
+ matrices over finite field this function does not even generate
262
+ all of them: for example ``Matrix.random(GF(3), 2, algorithm='unimodular')``
263
+ never generates ``[[2,0],[0,2]]``. This function is made for
264
+ teaching purposes.
265
+
266
+ .. warning::
267
+
268
+ An upper bound on the absolute value of the entries may be set
269
+ when the ``algorithm`` is ``echelonizable`` or ``unimodular``.
270
+ In these cases it is possible for this constructor to fail with
271
+ a :exc:`ValueError`. If you *must* have this routine return
272
+ successfully, do not set ``upper_bound``. This behavior can
273
+ be partially controlled by a ``max_tries`` keyword.
274
+
275
+ .. NOTE::
276
+
277
+ When constructing matrices with random entries and no
278
+ additional properties (i.e. when ``algorithm='randomize'``),
279
+ most of the randomness is controlled by the ``random_element``
280
+ method for elements of the base ring of the matrix, so the
281
+ documentation of that method may be relevant or useful.
282
+
283
+ EXAMPLES:
284
+
285
+ Random integer matrices. With no arguments, the majority of the entries
286
+ are zero, -1, and 1, and rarely "large." ::
287
+
288
+ sage: from collections import defaultdict
289
+ sage: total_count = 0
290
+ sage: dic = defaultdict(Integer)
291
+ sage: def add_samples(*args, **kwds):
292
+ ....: global dic, total_count
293
+ ....: for _ in range(100):
294
+ ....: A = random_matrix(*args, **kwds)
295
+ ....: for a in A.list():
296
+ ....: dic[a] += 1
297
+ ....: total_count += 1.0
298
+
299
+ sage: expected = lambda n : 2 / (5*abs(n)*(abs(n) + 1)) if n != 0 else 1/5
300
+ sage: expected(0)
301
+ 1/5
302
+ sage: expected(0) == expected(1) == expected(-1)
303
+ True
304
+ sage: expected(100)
305
+ 1/25250
306
+ sage: add_samples(ZZ, 5, 5)
307
+ sage: while not all(abs(dic[a]/total_count - expected(a)) < 0.001 for a in dic):
308
+ ....: add_samples(ZZ, 5, 5)
309
+
310
+ The ``distribution`` keyword set to ``uniform`` will limit values
311
+ between -2 and 2. ::
312
+
313
+ sage: expected = lambda n : 1/5 if n in range(-2, 3) else 0
314
+ sage: total_count = 0
315
+ sage: dic = defaultdict(Integer)
316
+ sage: add_samples(ZZ, 5, 5, distribution='uniform')
317
+ sage: while not all(abs(dic[a]/total_count - expected(a)) < 0.001 for a in dic):
318
+ ....: add_samples(ZZ, 5, 5, distribution='uniform')
319
+
320
+ The ``x`` and ``y`` keywords can be used to distribute entries uniformly.
321
+ When both are used ``x`` is the minimum and ``y`` is one greater than
322
+ the maximum. ::
323
+
324
+ sage: expected = lambda n : 1/30 if n in range(70, 100) else 0
325
+ sage: total_count = 0
326
+ sage: dic = defaultdict(Integer)
327
+ sage: add_samples(ZZ, 4, 8, x=70, y=100)
328
+ sage: while not all(abs(dic[a]/total_count - expected(a)) < 0.001 for a in dic):
329
+ ....: add_samples(ZZ, 4, 8, x=70, y=100)
330
+
331
+ sage: expected = lambda n : 1/10 if n in range(-5, 5) else 0
332
+ sage: total_count = 0
333
+ sage: dic = defaultdict(Integer)
334
+ sage: add_samples(ZZ, 3, 7, x=-5, y=5)
335
+ sage: while not all(abs(dic[a]/total_count - expected(a)) < 0.001 for a in dic):
336
+ ....: add_samples(ZZ, 3, 7, x=-5, y=5)
337
+
338
+ If only ``x`` is given, then it is used as the upper bound of a range
339
+ starting at 0. ::
340
+
341
+ sage: expected = lambda n : 1/25 if n in range(25) else 0
342
+ sage: total_count = 0
343
+ sage: dic = defaultdict(Integer)
344
+ sage: add_samples(ZZ, 5, 5, x=25)
345
+ sage: while not all(abs(dic[a]/total_count - expected(a)) < 0.001 for a in dic):
346
+ ....: add_samples(ZZ, 5, 5, x=25)
347
+
348
+ To control the number of nonzero entries, use the ``density`` keyword
349
+ at a value strictly below the default of 1.0. The ``density`` keyword
350
+ is used to compute the number of entries per row that will be nonzero, but the
351
+ same entry may be selected more than once. So the value provided will
352
+ be an upper bound for the density of the created matrix. Note that for
353
+ a square matrix it is only necessary to set a single dimension. ::
354
+
355
+ sage: def add_sample(*args, **kwds):
356
+ ....: global density_sum, total_count
357
+ ....: total_count += 1.0
358
+ ....: A = random_matrix(*args, **kwds)
359
+ ....: density_sum += float(A.density())
360
+
361
+ sage: # needs sage.libs.linbox (otherwise timeout)
362
+ sage: density_sum = 0.0
363
+ sage: total_count = 0.0
364
+ sage: add_sample(ZZ, 5, x=-10, y=10, density=0.75)
365
+ sage: expected_density = (1 - (4/5)^3)
366
+ sage: float(expected_density)
367
+ 0.488
368
+ sage: while abs(density_sum/total_count - expected_density) > 0.001:
369
+ ....: add_sample(ZZ, 5, x=-10, y=10, density=0.75)
370
+
371
+ sage: # needs sage.libs.linbox (otherwise timeout)
372
+ sage: density_sum = 0.0
373
+ sage: total_count = 0.0
374
+ sage: add_sample(ZZ, 5, x=20, y=30, density=0.75)
375
+ sage: while abs(density_sum/total_count - expected_density) > 0.001:
376
+ ....: add_sample(ZZ, 5, x=20, y=30, density=0.75)
377
+
378
+ sage: # needs sage.libs.linbox (otherwise timeout)
379
+ sage: density_sum = 0.0
380
+ sage: total_count = 0.0
381
+ sage: add_sample(ZZ, 100, x=20, y=30, density=0.75)
382
+ sage: expected_density = (1 - (99/100)^75)
383
+ sage: float(expected_density)
384
+ 0.529...
385
+ sage: while abs(density_sum/total_count - expected_density) > 0.001:
386
+ ....: add_sample(ZZ, 100, x=20, y=30, density=0.75)
387
+
388
+ For a matrix with low density it may be advisable to insist on a sparse
389
+ representation, as this representation is not selected automatically. ::
390
+
391
+ sage: A = random_matrix(ZZ, 5, 5)
392
+ sage: A.is_sparse()
393
+ False
394
+ sage: A = random_matrix(ZZ, 5, 5, sparse=True)
395
+ sage: A.is_sparse()
396
+ True
397
+
398
+ For algorithm testing you might want to control the number of bits,
399
+ say 10,000 entries, each limited to 16 bits. ::
400
+
401
+ sage: # needs sage.libs.linbox (otherwise timeout)
402
+ sage: A = random_matrix(ZZ, 100, 100, x=2^16); A
403
+ 100 x 100 dense matrix over Integer Ring (use the '.str()' method to see the entries)
404
+
405
+ One can prescribe a specific matrix implementation::
406
+
407
+ sage: K.<a> = FiniteField(2^8) # needs sage.rings.finite_rings
408
+ sage: type(random_matrix(K, 2, 5)) # needs sage.libs.m4ri sage.rings.finite_rings
409
+ <class 'sage.matrix.matrix_gf2e_dense.Matrix_gf2e_dense'>
410
+ sage: type(random_matrix(K, 2, 5, implementation='generic')) # needs sage.rings.finite_rings
411
+ <class 'sage.matrix.matrix_generic_dense.Matrix_generic_dense'>
412
+
413
+ Random rational matrices. Now ``num_bound`` and ``den_bound`` control the
414
+ generation of random elements, by specifying limits on the absolute value of
415
+ numerators and denominators (respectively). Entries will be positive and
416
+ negative (map the absolute value function through the entries to get all
417
+ positive values). If either the numerator or denominator bound (or both)
418
+ is not used, then the values default to ``2``::
419
+
420
+ sage: A = random_matrix(QQ, 2, 8, num_bound=20, den_bound=4)
421
+ sage: A.dimensions()
422
+ (2, 8)
423
+ sage: type(A) # needs sage.libs.flint
424
+ <class 'sage.matrix.matrix_rational_dense.Matrix_rational_dense'>
425
+ sage: all(a.numerator() in range(-20, 21) and
426
+ ....: a.denominator() in range(1, 5)
427
+ ....: for a in A.list())
428
+ True
429
+
430
+ sage: A = random_matrix(QQ, 4, density=0.5, sparse=True)
431
+ sage: type(A)
432
+ <class 'sage.matrix.matrix_rational_sparse.Matrix_rational_sparse'>
433
+ sage: A.density() <= 0.5
434
+ True
435
+
436
+ sage: A = random_matrix(QQ, 3, 10, num_bound = 99, den_bound = 99)
437
+ sage: positives = list(map(abs, A.list()))
438
+ sage: A1 = matrix(QQ, 3, 10, positives)
439
+ sage: all(abs(A.list()[i]) == A1.list()[i] for i in range(30))
440
+ True
441
+ sage: all(a.numerator() in range(100) and
442
+ ....: a.denominator() in range(1, 100)
443
+ ....: for a in A1.list())
444
+ True
445
+
446
+ sage: A = random_matrix(QQ, 4, 10, den_bound = 10)
447
+ sage: all(a.numerator() in range(-2, 3) and
448
+ ....: a.denominator() in range(1, 11)
449
+ ....: for a in A.list())
450
+ True
451
+
452
+ sage: A = random_matrix(QQ, 4, 10)
453
+ sage: all(a.numerator() in range(-2, 3) and
454
+ ....: a.denominator() in range(1, 3)
455
+ ....: for a in A.list())
456
+ True
457
+
458
+ Random matrices over other rings. Several classes of matrices have specialized
459
+ ``randomize()`` methods. You can locate these with the Sage command::
460
+
461
+ search_def('randomize')
462
+
463
+ The default implementation of :meth:`~sage.matrix.matrix2.randomize` relies
464
+ on the ``random_element()`` method for the base ring. The ``density`` and
465
+ ``sparse`` keywords behave as described above. Since we have a different
466
+ randomisation when using the optional meataxe package, we have to make sure
467
+ that we use the default implementation in this test::
468
+
469
+ sage: K.<a> = FiniteField(3^2) # needs sage.rings.finite_rings
470
+ sage: A = random_matrix(K, 2, 5, implementation='generic') # needs sage.rings.finite_rings
471
+ sage: type(A)
472
+ <class 'sage.matrix.matrix_generic_dense.Matrix_generic_dense'>
473
+ sage: A.base_ring() is K # needs sage.rings.finite_rings
474
+ True
475
+ sage: TestSuite(A).run()
476
+
477
+ sage: A = random_matrix(RR, 3, 4, density=0.66)
478
+ sage: type(A)
479
+ <class 'sage.matrix.matrix_generic_dense.Matrix_generic_dense'>
480
+ sage: A.base_ring() is RR
481
+ True
482
+ sage: TestSuite(A).run()
483
+
484
+ sage: A = random_matrix(ComplexField(32), 3, density=0.8, sparse=True)
485
+ sage: A.is_sparse()
486
+ True
487
+ sage: type(A)
488
+ <class 'sage.matrix.matrix_generic_sparse.Matrix_generic_sparse'>
489
+ sage: A.base_ring() is ComplexField(32)
490
+ True
491
+ sage: TestSuite(A).run()
492
+
493
+ Random matrices in echelon form. The ``algorithm='echelon_form'`` keyword,
494
+ along with a requested number of nonzero rows (``num_pivots``) will return
495
+ a random matrix in echelon form. When the base ring is ``QQ`` the result has integer
496
+ entries. Other exact rings may be also specified. ::
497
+
498
+ sage: A = random_matrix(QQ, 4, 8, algorithm='echelon_form', num_pivots=3)
499
+ sage: A.base_ring()
500
+ Rational Field
501
+ sage: (A.nrows(), A.ncols())
502
+ (4, 8)
503
+ sage: A in sage.matrix.matrix_space.MatrixSpace(ZZ, 4, 8)
504
+ True
505
+ sage: A.rank()
506
+ 3
507
+ sage: A == A.rref()
508
+ True
509
+
510
+ For more, see the documentation of the :func:`~sage.matrix.constructor.random_rref_matrix`
511
+ function. In the notebook or at the Sage command-line, first execute the following to make
512
+ this further documentation available::
513
+
514
+ from sage.matrix.constructor import random_rref_matrix
515
+
516
+ Random matrices with predictable echelon forms. The ``algorithm='echelonizable'``
517
+ keyword, along with a requested rank (``rank``) and optional size control
518
+ (``upper_bound``) will return a random matrix in echelon form. When the
519
+ base ring is ``ZZ`` or ``QQ`` the result has integer entries, whose magnitudes
520
+ can be limited by the value of ``upper_bound``, and the echelon form of the
521
+ matrix also has integer entries. Other exact rings may be also
522
+ specified, but there is no notion of controlling the size. Square matrices
523
+ of full rank generated by this function always have determinant one, and
524
+ can be constructed with the ``unimodular`` keyword. ::
525
+
526
+ sage: A = random_matrix(QQ, 4, 8, algorithm='echelonizable', rank=3, upper_bound=60)
527
+ sage: A.base_ring()
528
+ Rational Field
529
+ sage: (A.nrows(), A.ncols())
530
+ (4, 8)
531
+ sage: A in sage.matrix.matrix_space.MatrixSpace(ZZ, 4, 8)
532
+ True
533
+ sage: A.rank()
534
+ 3
535
+ sage: all(abs(x)<60 for x in A.list())
536
+ True
537
+ sage: A.rref() in sage.matrix.matrix_space.MatrixSpace(ZZ, 4, 8)
538
+ True
539
+
540
+ For more, see the documentation of the :func:`~sage.matrix.constructor.random_echelonizable_matrix`
541
+ function. In the notebook or at the Sage command-line, first execute the following to make
542
+ this further documentation available::
543
+
544
+ from sage.matrix.constructor import random_echelonizable_matrix
545
+
546
+ Random diagonalizable matrices. The ``algorithm='diagonalizable'`` keyword,
547
+ along with a requested matrix size (``size``) and optional lists of
548
+ eigenvalues (``eigenvalues``) and the corresponding eigenspace
549
+ dimensions (``dimensions``) will return a random diagonalizable matrix.
550
+ When the eigenvalues and dimensions are not specified the result will have
551
+ randomly generated values for both that fit with the designated size. ::
552
+
553
+ sage: A = random_matrix(QQ, 5, algorithm='diagonalizable', # random
554
+ ....: eigenvalues=[2,3,-1], dimensions=[1,2,2]); A
555
+ sage: all(x in ZZ for x in (A - (2*identity_matrix(5))).rref().list())
556
+ True
557
+ sage: all(x in ZZ for x in (A - 3*identity_matrix(5)).rref().list())
558
+ True
559
+ sage: all(x in ZZ for x in (A - (-1)*identity_matrix(5)).rref().list())
560
+ True
561
+ sage: A.jordan_form() # needs sage.combinat sage.libs.pari
562
+ [ 2| 0| 0| 0| 0]
563
+ [--+--+--+--+--]
564
+ [ 0| 3| 0| 0| 0]
565
+ [--+--+--+--+--]
566
+ [ 0| 0| 3| 0| 0]
567
+ [--+--+--+--+--]
568
+ [ 0| 0| 0|-1| 0]
569
+ [--+--+--+--+--]
570
+ [ 0| 0| 0| 0|-1]
571
+
572
+ For more, see the documentation of the :func:`~sage.matrix.constructor.random_diagonalizable_matrix`
573
+ function. In the notebook or at the Sage command-line, first execute the following to make
574
+ this further documentation available::
575
+
576
+ from sage.matrix.constructor import random_diagonalizable_matrix
577
+
578
+ Random matrices with predictable subspaces. The ``algorithm='subspaces'``
579
+ keyword, along with an optional rank (``rank``) will return
580
+ a matrix whose natural basis vectors for its four fundamental subspaces, if computed as
581
+ described in the documentation of the :func:`~sage.matrix.constructor.random_subspaces_matrix`
582
+ contain only integer entries. If ``rank``, is not set, the
583
+ rank of the matrix will be generated randomly. ::
584
+
585
+ sage: B = random_matrix(QQ, 5, 6, algorithm='subspaces', rank=3); B # random
586
+ sage: B_expanded = B.augment(identity_matrix(5)).rref()
587
+ sage: (B.nrows(), B.ncols())
588
+ (5, 6)
589
+ sage: all(x in ZZ for x in B_expanded.list())
590
+ True
591
+ sage: C = B_expanded.submatrix(0, 0, B.nrows() - B.nullity(), B.ncols())
592
+ sage: L = B_expanded.submatrix(B.nrows() - B.nullity(), B.ncols())
593
+ sage: B.right_kernel() == C.right_kernel()
594
+ True
595
+ sage: B.row_space() == C.row_space()
596
+ True
597
+ sage: B.column_space() == L.right_kernel()
598
+ True
599
+ sage: B.left_kernel() == L.row_space()
600
+ True
601
+
602
+ For more, see the documentation of the :func:`~sage.matrix.constructor.random_subspaces_matrix`
603
+ function. In the notebook or at the Sage command-line, first execute the following to make
604
+ this further documentation available::
605
+
606
+ from sage.matrix.constructor import random_subspaces_matrix
607
+
608
+ Random unimodular matrices. The ``algorithm='unimodular'``
609
+ keyword, along with an optional entry size control (``upper_bound``)
610
+ will return a matrix of determinant 1. When the base ring is ``ZZ``
611
+ or ``QQ`` the result has integer entries, whose magnitudes
612
+ can be limited by the value of ``upper_bound``. ::
613
+
614
+ sage: C = random_matrix(QQ, 5, algorithm='unimodular', upper_bound=70); C # random
615
+ sage: det(C)
616
+ 1
617
+ sage: C.base_ring()
618
+ Rational Field
619
+ sage: (C.nrows(), C.ncols())
620
+ (5, 5)
621
+ sage: all(abs(x)<70 for x in C.list())
622
+ True
623
+
624
+ For more, see the documentation of the :func:`~sage.matrix.constructor.random_unimodular_matrix`
625
+ function. In the notebook or at the Sage command-line, first execute the following to make
626
+ this further documentation available::
627
+
628
+ from sage.matrix.constructor import random_unimodular_matrix
629
+
630
+ TESTS:
631
+
632
+ We return an error for a bogus value of ``algorithm``::
633
+
634
+ sage: random_matrix(ZZ, 5, algorithm='bogus')
635
+ Traceback (most recent call last):
636
+ ...
637
+ ValueError: random matrix algorithm "bogus" is not recognized
638
+
639
+ AUTHOR:
640
+
641
+ - William Stein (2007-02-06)
642
+
643
+ - Rob Beezer (2010-08-25) Documentation, code to allow additional types of output
644
+ """
645
+ if ncols is None:
646
+ ncols = nrows
647
+ sparse = kwds.pop('sparse', False)
648
+ # Construct the parent of the desired matrix
649
+ parent = matrix_space.MatrixSpace(ring, nrows, ncols, sparse=sparse, implementation=implementation)
650
+ if algorithm == 'randomize':
651
+ density = kwds.pop('density', None)
652
+ # zero matrix is immutable, copy is mutable
653
+ A = copy(parent.zero_matrix())
654
+ if density is None:
655
+ A.randomize(density=float(1), nonzero=False, *args, **kwds)
656
+ else:
657
+ A.randomize(density=density, nonzero=True, *args, **kwds)
658
+ return A
659
+ elif algorithm == 'echelon_form':
660
+ return random_rref_matrix(parent, *args, **kwds)
661
+ elif algorithm == 'echelonizable':
662
+ return random_echelonizable_matrix(parent, *args, **kwds)
663
+ elif algorithm == 'diagonalizable':
664
+ return random_diagonalizable_matrix(parent, *args, **kwds)
665
+ elif algorithm == 'subspaces':
666
+ return random_subspaces_matrix(parent, *args, **kwds)
667
+ elif algorithm == 'unimodular':
668
+ return random_unimodular_matrix(parent, *args, **kwds)
669
+ else:
670
+ raise ValueError('random matrix algorithm "%s" is not recognized' % algorithm)
671
+
672
+
673
+ @matrix_method
674
+ def diagonal_matrix(arg0=None, arg1=None, arg2=None, sparse=True):
675
+ r"""
676
+ Return a square matrix with specified diagonal entries, and zeros elsewhere.
677
+
678
+ FORMATS:
679
+
680
+ 1. diagonal_matrix(entries)
681
+
682
+ 2. diagonal_matrix(nrows, entries)
683
+
684
+ 3. diagonal_matrix(ring, entries)
685
+
686
+ 4. diagonal_matrix(ring, nrows, entries)
687
+
688
+ INPUT:
689
+
690
+ - ``entries`` -- the values to place along the diagonal
691
+ of the returned matrix. This may be a flat list, a
692
+ flat tuple, a vector or free module element, or
693
+ a one-dimensional NumPy array.
694
+
695
+ - ``nrows`` -- the size of the returned matrix, which
696
+ will have an equal number of columns
697
+
698
+ - ``ring`` -- the ring containing the entries of the
699
+ diagonal entries. This may not be specified in
700
+ combination with a NumPy array.
701
+
702
+ - ``sparse`` -- boolean (default: ``True``); whether or not
703
+ the result has a sparse implementation
704
+
705
+ OUTPUT:
706
+
707
+ A square matrix over the given ``ring`` with a size
708
+ given by ``nrows``. If the ring is not given it
709
+ is inferred from the given entries. The values on
710
+ the diagonal of the returned matrix come from ``entries``.
711
+ If the number of entries is not enough to fill the whole
712
+ diagonal, it is padded with zeros.
713
+
714
+ EXAMPLES:
715
+
716
+ We first demonstrate each of the input formats with various
717
+ different ways to specify the entries.
718
+
719
+ Format 1: a flat list of entries. ::
720
+
721
+ sage: A = diagonal_matrix([2, 1.3, 5]); A
722
+ [ 2.00000000000000 0.000000000000000 0.000000000000000]
723
+ [0.000000000000000 1.30000000000000 0.000000000000000]
724
+ [0.000000000000000 0.000000000000000 5.00000000000000]
725
+ sage: A.parent()
726
+ Full MatrixSpace of 3 by 3 sparse matrices over Real Field with 53 bits of precision
727
+
728
+ Format 2: size specified, a tuple with initial entries. Note that a short list of entries
729
+ is effectively padded with zeros. ::
730
+
731
+ sage: A = diagonal_matrix(3, (4, 5)); A
732
+ [4 0 0]
733
+ [0 5 0]
734
+ [0 0 0]
735
+ sage: A.parent()
736
+ Full MatrixSpace of 3 by 3 sparse matrices over Integer Ring
737
+
738
+ Format 3: ring specified, a vector of entries. ::
739
+
740
+ sage: A = diagonal_matrix(QQ, vector(ZZ, [1,2,3])); A
741
+ [1 0 0]
742
+ [0 2 0]
743
+ [0 0 3]
744
+ sage: A.parent()
745
+ Full MatrixSpace of 3 by 3 sparse matrices over Rational Field
746
+
747
+ Format 4: ring, size and list of entries. ::
748
+
749
+ sage: A = diagonal_matrix(FiniteField(3), 3, [2, 16]); A
750
+ [2 0 0]
751
+ [0 1 0]
752
+ [0 0 0]
753
+ sage: A.parent()
754
+ Full MatrixSpace of 3 by 3 sparse matrices over Finite Field of size 3
755
+
756
+ NumPy arrays may be used as input. ::
757
+
758
+ sage: # needs numpy
759
+ sage: import numpy
760
+ sage: entries = numpy.array([1.2, 5.6]); entries
761
+ array([1.2, 5.6])
762
+ sage: A = diagonal_matrix(3, entries); A
763
+ [1.2 0.0 0.0]
764
+ [0.0 5.6 0.0]
765
+ [0.0 0.0 0.0]
766
+ sage: A.parent()
767
+ Full MatrixSpace of 3 by 3 sparse matrices over Real Double Field
768
+
769
+ sage: # needs numpy
770
+ sage: j = complex(0,1)
771
+ sage: entries = numpy.array([2.0+j, 8.1, 3.4+2.6*j]); entries
772
+ array([2. +1.j , 8.1+0.j , 3.4+2.6j])
773
+ sage: A = diagonal_matrix(entries); A
774
+ [2.0 + 1.0*I 0.0 0.0]
775
+ [ 0.0 8.1 0.0]
776
+ [ 0.0 0.0 3.4 + 2.6*I]
777
+ sage: A.parent()
778
+ Full MatrixSpace of 3 by 3 sparse matrices over Complex Double Field
779
+
780
+ sage: # needs numpy
781
+ sage: entries = numpy.array([4, 5, 6])
782
+ sage: A = diagonal_matrix(entries); A
783
+ [4 0 0]
784
+ [0 5 0]
785
+ [0 0 6]
786
+ sage: A.parent()
787
+ Full MatrixSpace of 3 by 3 sparse matrices over Integer Ring
788
+
789
+ sage: entries = numpy.array([4.1, 5.2, 6.3]) # needs numpy
790
+ sage: A = diagonal_matrix(ZZ, entries); A # needs numpy
791
+ Traceback (most recent call last):
792
+ ...
793
+ TypeError: unable to convert 4.1 to an element of Integer Ring
794
+
795
+ By default returned matrices have a sparse implementation. This can be changed
796
+ when using any of the formats. ::
797
+
798
+ sage: A = diagonal_matrix([1,2,3], sparse=False)
799
+ sage: A.parent()
800
+ Full MatrixSpace of 3 by 3 dense matrices over Integer Ring
801
+
802
+ An empty list and no ring specified defaults to the integers. ::
803
+
804
+ sage: A = diagonal_matrix([])
805
+ sage: A.parent()
806
+ Full MatrixSpace of 0 by 0 sparse matrices over Integer Ring
807
+
808
+ Giving the entries improperly may first complain about not being iterable::
809
+
810
+ sage: diagonal_matrix(QQ, 5, 10)
811
+ Traceback (most recent call last):
812
+ ...
813
+ TypeError: 'sage.rings.integer.Integer' object is not iterable
814
+
815
+ Giving too many entries will raise an error. ::
816
+
817
+ sage: diagonal_matrix(QQ, 3, [1,2,3,4])
818
+ Traceback (most recent call last):
819
+ ...
820
+ ValueError: number of diagonal matrix entries (4) exceeds the requested matrix size (3)
821
+
822
+ A negative size sometimes causes the error that there are too many elements. ::
823
+
824
+ sage: diagonal_matrix(-2, [2])
825
+ Traceback (most recent call last):
826
+ ...
827
+ ValueError: number of diagonal matrix entries (1) exceeds the requested matrix size (-2)
828
+
829
+ Types for the entries need to be iterable (tuple, list, vector, NumPy array,
830
+ etc)::
831
+
832
+ sage: diagonal_matrix(x^2) # needs sage.symbolic
833
+ Traceback (most recent call last):
834
+ ...
835
+ TypeError: 'sage.symbolic.expression.Expression' object is not iterable
836
+
837
+ TESTS::
838
+
839
+ sage: A = diagonal_matrix(reversed(range(4)))
840
+
841
+ AUTHOR:
842
+
843
+ - Rob Beezer (2011-01-11): total rewrite
844
+ """
845
+ # Roll arguments leftward
846
+ #
847
+ # Leads with a ring?
848
+ # Formats 3, 4, else remains None
849
+ ring = None
850
+ if arg0 in Rings():
851
+ ring = arg0
852
+ arg0 = arg1
853
+ arg1 = arg2
854
+ # Size of matrix specified?
855
+ # Formats 2, 4
856
+ nrows = None
857
+ if isinstance(arg0, (Integer, int)):
858
+ nrows = arg0
859
+ arg0 = arg1
860
+ # Object holding entries
861
+ # Formats 1, 2, 3, 4
862
+ entries = arg0
863
+
864
+ # sanity check for entries
865
+ types = (list, tuple)
866
+ try:
867
+ from numpy import ndarray
868
+ except ImportError:
869
+ pass
870
+ else:
871
+ types += (ndarray,)
872
+ if not isinstance(entries, types):
873
+ entries = list(entries)
874
+
875
+ # Reconcile matrix size and number of entries
876
+ try:
877
+ nentries = len(entries)
878
+ except TypeError:
879
+ raise TypeError('unable to determine number of entries for diagonal matrix construction')
880
+ # sometimes catches a negative size
881
+ if nrows is not None and nentries > nrows:
882
+ raise ValueError('number of diagonal matrix entries (%s) exceeds the requested matrix size (%s)' % (nentries, nrows))
883
+ if nrows is None:
884
+ nrows = nentries
885
+
886
+ # provide a default ring for an empty list
887
+ if not nentries and ring is None:
888
+ ring = ZZ
889
+
890
+ # Convert entries to a list v over a common ring
891
+ from sage.modules.free_module_element import prepare
892
+ v, ring = prepare(entries, ring)
893
+
894
+ # Create a "diagonal" dictionary for matrix constructor
895
+ # If nentries < nrows, diagonal is effectively padded with zeros at end
896
+ w = {(i, i): v[i] for i in range(len(v))}
897
+
898
+ # Ship ring, matrix size, dictionary to matrix constructor
899
+ if ring is None:
900
+ return matrix(nrows, nrows, w, sparse=sparse)
901
+ else:
902
+ return matrix(ring, nrows, nrows, w, sparse=sparse)
903
+
904
+
905
+ @matrix_method
906
+ def identity_matrix(ring, n=0, sparse=False):
907
+ r"""
908
+ Return the `n \times n` identity matrix over the given
909
+ ring.
910
+
911
+ The default ring is the integers.
912
+
913
+ EXAMPLES::
914
+
915
+ sage: M = identity_matrix(QQ, 2); M
916
+ [1 0]
917
+ [0 1]
918
+ sage: M.parent()
919
+ Full MatrixSpace of 2 by 2 dense matrices over Rational Field
920
+ sage: M = identity_matrix(2); M
921
+ [1 0]
922
+ [0 1]
923
+ sage: M.parent()
924
+ Full MatrixSpace of 2 by 2 dense matrices over Integer Ring
925
+ sage: M.is_mutable()
926
+ True
927
+ sage: M = identity_matrix(3, sparse=True); M
928
+ [1 0 0]
929
+ [0 1 0]
930
+ [0 0 1]
931
+ sage: M.parent()
932
+ Full MatrixSpace of 3 by 3 sparse matrices over Integer Ring
933
+ sage: M.is_mutable()
934
+ True
935
+ """
936
+ if isinstance(ring, (Integer, int)):
937
+ n = ring
938
+ ring = ZZ
939
+ return matrix_space.MatrixSpace(ring, n, n, sparse)(1)
940
+
941
+
942
+ @matrix_method
943
+ def lehmer(ring, n=0):
944
+ r"""
945
+ Return the `n \times n` Lehmer matrix.
946
+
947
+ The default ring is the rationals.
948
+
949
+ Element `(i, j)` in the Lehmer matrix is
950
+ `min(i, j)/max(i, j)`.
951
+
952
+ See :wikipedia:`Lehmer_matrix`.
953
+
954
+ EXAMPLES::
955
+
956
+ sage: matrix.lehmer(3)
957
+ [ 1 1/2 1/3]
958
+ [1/2 1 2/3]
959
+ [1/3 2/3 1]
960
+ """
961
+ from sage.sets.integer_range import IntegerRange
962
+
963
+ if isinstance(ring, (Integer, int)):
964
+ n = ring
965
+ ring = QQ
966
+ return matrix_space.MatrixSpace(ring, n, n).matrix([[min(i, j)/max(i, j) for i in IntegerRange(1, n+1)] for j in IntegerRange(1, n+1)])
967
+
968
+
969
+ @matrix_method
970
+ def zero_matrix(ring, nrows=None, ncols=None, sparse=False):
971
+ r"""
972
+ Return the `nrows \times ncols` zero matrix over the given
973
+ ring.
974
+
975
+ The default ring is the integers.
976
+
977
+ EXAMPLES::
978
+
979
+ sage: M = zero_matrix(QQ, 2); M
980
+ [0 0]
981
+ [0 0]
982
+ sage: M.parent()
983
+ Full MatrixSpace of 2 by 2 dense matrices over Rational Field
984
+ sage: M = zero_matrix(2, 3); M
985
+ [0 0 0]
986
+ [0 0 0]
987
+ sage: M.parent()
988
+ Full MatrixSpace of 2 by 3 dense matrices over Integer Ring
989
+ sage: M.is_mutable()
990
+ True
991
+ sage: M = zero_matrix(3, 1, sparse=True); M
992
+ [0]
993
+ [0]
994
+ [0]
995
+ sage: M.parent()
996
+ Full MatrixSpace of 3 by 1 sparse matrices over Integer Ring
997
+ sage: M.is_mutable()
998
+ True
999
+ sage: matrix.zero(5)
1000
+ [0 0 0 0 0]
1001
+ [0 0 0 0 0]
1002
+ [0 0 0 0 0]
1003
+ [0 0 0 0 0]
1004
+ [0 0 0 0 0]
1005
+
1006
+ TESTS:
1007
+
1008
+ Check that :issue:`38221` is fixed::
1009
+
1010
+ sage: # needs sage.groups
1011
+ sage: G = CyclicPermutationGroup(7)
1012
+ sage: R = GF(2)
1013
+ sage: A = G.algebra(R)
1014
+ sage: zero_matrix(A, 3, 3)
1015
+ [0 0 0]
1016
+ [0 0 0]
1017
+ [0 0 0]
1018
+ """
1019
+ if isinstance(ring, (Integer, int)):
1020
+ nrows, ncols = (ring, nrows)
1021
+ ring = ZZ
1022
+ return matrix_space.MatrixSpace(ring, nrows, ncols, sparse).matrix(None)
1023
+
1024
+
1025
+ @matrix_method
1026
+ def ones_matrix(ring, nrows=None, ncols=None, sparse=False):
1027
+ r"""
1028
+ Return a matrix with all entries equal to 1.
1029
+
1030
+ CALL FORMATS:
1031
+
1032
+ In each case, the optional keyword ``sparse`` can be used.
1033
+
1034
+ 1. ones_matrix(ring, nrows, ncols)
1035
+ 2. ones_matrix(ring, nrows)
1036
+ 3. ones_matrix(nrows, ncols)
1037
+ 4. ones_matrix(nrows)
1038
+
1039
+ INPUT:
1040
+
1041
+ - ``ring`` -- (default: ``ZZ``) base ring for the matrix
1042
+ - ``nrows`` -- number of rows in the matrix
1043
+ - ``ncols`` -- number of columns in the matrix;
1044
+ if omitted, defaults to the number of rows, producing a square matrix
1045
+ - ``sparse`` -- (default: ``False``) if ``True`` creates a sparse representation
1046
+
1047
+ OUTPUT:
1048
+
1049
+ A matrix of size ``nrows`` by ``ncols`` over the ``ring`` with every
1050
+ entry equal to 1. While the result is far from sparse, you may wish
1051
+ to choose a sparse representation when mixing this matrix with
1052
+ other sparse matrices.
1053
+
1054
+ EXAMPLES:
1055
+
1056
+ A call specifying the ring and the size. ::
1057
+
1058
+ sage: M= ones_matrix(QQ, 2, 5); M
1059
+ [1 1 1 1 1]
1060
+ [1 1 1 1 1]
1061
+ sage: M.parent()
1062
+ Full MatrixSpace of 2 by 5 dense matrices over Rational Field
1063
+
1064
+ Without specifying the number of columns, the result is square. ::
1065
+
1066
+ sage: M = ones_matrix(RR, 2); M
1067
+ [1.00000000000000 1.00000000000000]
1068
+ [1.00000000000000 1.00000000000000]
1069
+ sage: M.parent()
1070
+ Full MatrixSpace of 2 by 2 dense matrices over Real Field with 53 bits of precision
1071
+
1072
+ The ring defaults to the integers if not given. ::
1073
+
1074
+ sage: M = ones_matrix(2, 3); M
1075
+ [1 1 1]
1076
+ [1 1 1]
1077
+ sage: M.parent()
1078
+ Full MatrixSpace of 2 by 3 dense matrices over Integer Ring
1079
+
1080
+ A lone integer input produces a square matrix over the integers. ::
1081
+
1082
+ sage: M = ones_matrix(3); M
1083
+ [1 1 1]
1084
+ [1 1 1]
1085
+ [1 1 1]
1086
+ sage: M.parent()
1087
+ Full MatrixSpace of 3 by 3 dense matrices over Integer Ring
1088
+
1089
+ The result can have a sparse implementation. ::
1090
+
1091
+ sage: M = ones_matrix(3, 1, sparse=True); M
1092
+ [1]
1093
+ [1]
1094
+ [1]
1095
+ sage: M.parent()
1096
+ Full MatrixSpace of 3 by 1 sparse matrices over Integer Ring
1097
+
1098
+ Giving just a ring will yield an error. ::
1099
+
1100
+ sage: ones_matrix(CC)
1101
+ Traceback (most recent call last):
1102
+ ...
1103
+ ValueError: constructing an all ones matrix requires at least one dimension
1104
+ """
1105
+ if isinstance(ring, (Integer, int)):
1106
+ nrows, ncols = (ring, nrows)
1107
+ ring = ZZ
1108
+ if nrows is None:
1109
+ raise ValueError("constructing an all ones matrix requires at least one dimension")
1110
+ if ncols is None:
1111
+ nents = nrows**2
1112
+ else:
1113
+ nents = nrows*ncols
1114
+ one = ring(1)
1115
+ return matrix_space.MatrixSpace(ring, nrows, ncols, sparse).matrix([one]*nents)
1116
+
1117
+
1118
+ @matrix_method
1119
+ def elementary_matrix(arg0, arg1=None, **kwds):
1120
+ r"""
1121
+ Create a square matrix that corresponds to a row operation or a column operation.
1122
+
1123
+ FORMATS:
1124
+
1125
+ In each case, ``R`` is the base ring, and is optional. ``n`` is the size
1126
+ of the square matrix created. Any call may include the ``sparse`` keyword
1127
+ to determine the representation used. The default is ``False`` which
1128
+ leads to a dense representation. We describe the matrices by their
1129
+ associated row operation, see the output description for more.
1130
+
1131
+ - ``elementary_matrix(R, n, row1=i, row2=j)``
1132
+
1133
+ The matrix which swaps rows ``i`` and ``j``.
1134
+
1135
+ - ``elementary_matrix(R, n, row1=i, scale=s)``
1136
+
1137
+ The matrix which multiplies row ``i`` by ``s``.
1138
+
1139
+ - ``elementary_matrix(R, n, row1=i, row2=j, scale=s)``
1140
+
1141
+ The matrix which multiplies row ``j`` by ``s``
1142
+ and adds it to row ``i``.
1143
+
1144
+ Elementary matrices representing column operations are created
1145
+ in an entirely analogous way, replacing ``row1`` by ``col1`` and
1146
+ replacing ``row2`` by ``col2``.
1147
+
1148
+ Specifying the ring for entries of the matrix is optional. If it
1149
+ is not given, and a scale parameter is provided, then a ring containing
1150
+ the value of ``scale`` will be used. Otherwise, the ring defaults
1151
+ to the integers.
1152
+
1153
+ OUTPUT:
1154
+
1155
+ An elementary matrix is a square matrix that is very close to being
1156
+ an identity matrix. If ``E`` is an elementary matrix and ``A`` is any
1157
+ matrix with the same number of rows, then ``E*A`` is the result of
1158
+ applying a row operation to ``A``. This is how the three types
1159
+ created by this function are described. Similarly, an elementary matrix
1160
+ can be associated with a column operation, so if ``E`` has the same number
1161
+ of columns as ``A`` then ``A*E`` is the result of performing a column
1162
+ operation on ``A``.
1163
+
1164
+ An elementary matrix representing a row operation is created if ``row1``
1165
+ is specified, while an elementary matrix representing a column operation
1166
+ is created if ``col1`` is specified.
1167
+
1168
+ EXAMPLES:
1169
+
1170
+ Over the integers, creating row operations. Recall that row
1171
+ and column numbering begins at zero. ::
1172
+
1173
+ sage: A = matrix(ZZ, 4, 10, range(40)); A
1174
+ [ 0 1 2 3 4 5 6 7 8 9]
1175
+ [10 11 12 13 14 15 16 17 18 19]
1176
+ [20 21 22 23 24 25 26 27 28 29]
1177
+ [30 31 32 33 34 35 36 37 38 39]
1178
+
1179
+ sage: E = elementary_matrix(4, row1=1, row2=3); E
1180
+ [1 0 0 0]
1181
+ [0 0 0 1]
1182
+ [0 0 1 0]
1183
+ [0 1 0 0]
1184
+ sage: E*A
1185
+ [ 0 1 2 3 4 5 6 7 8 9]
1186
+ [30 31 32 33 34 35 36 37 38 39]
1187
+ [20 21 22 23 24 25 26 27 28 29]
1188
+ [10 11 12 13 14 15 16 17 18 19]
1189
+
1190
+ sage: E = elementary_matrix(4, row1=2, scale=10); E
1191
+ [ 1 0 0 0]
1192
+ [ 0 1 0 0]
1193
+ [ 0 0 10 0]
1194
+ [ 0 0 0 1]
1195
+ sage: E*A
1196
+ [ 0 1 2 3 4 5 6 7 8 9]
1197
+ [ 10 11 12 13 14 15 16 17 18 19]
1198
+ [200 210 220 230 240 250 260 270 280 290]
1199
+ [ 30 31 32 33 34 35 36 37 38 39]
1200
+
1201
+ sage: E = elementary_matrix(4, row1=2, row2=1, scale=10); E
1202
+ [ 1 0 0 0]
1203
+ [ 0 1 0 0]
1204
+ [ 0 10 1 0]
1205
+ [ 0 0 0 1]
1206
+ sage: E*A
1207
+ [ 0 1 2 3 4 5 6 7 8 9]
1208
+ [ 10 11 12 13 14 15 16 17 18 19]
1209
+ [120 131 142 153 164 175 186 197 208 219]
1210
+ [ 30 31 32 33 34 35 36 37 38 39]
1211
+
1212
+ Over the rationals, now as column operations. Recall that row
1213
+ and column numbering begins at zero. Checks now have the
1214
+ elementary matrix on the right. ::
1215
+
1216
+ sage: A = matrix(QQ, 5, 4, range(20)); A
1217
+ [ 0 1 2 3]
1218
+ [ 4 5 6 7]
1219
+ [ 8 9 10 11]
1220
+ [12 13 14 15]
1221
+ [16 17 18 19]
1222
+
1223
+ sage: E = elementary_matrix(QQ, 4, col1=1, col2=3); E
1224
+ [1 0 0 0]
1225
+ [0 0 0 1]
1226
+ [0 0 1 0]
1227
+ [0 1 0 0]
1228
+ sage: A*E
1229
+ [ 0 3 2 1]
1230
+ [ 4 7 6 5]
1231
+ [ 8 11 10 9]
1232
+ [12 15 14 13]
1233
+ [16 19 18 17]
1234
+
1235
+ sage: E = elementary_matrix(QQ, 4, col1=2, scale=1/2); E
1236
+ [ 1 0 0 0]
1237
+ [ 0 1 0 0]
1238
+ [ 0 0 1/2 0]
1239
+ [ 0 0 0 1]
1240
+ sage: A*E
1241
+ [ 0 1 1 3]
1242
+ [ 4 5 3 7]
1243
+ [ 8 9 5 11]
1244
+ [12 13 7 15]
1245
+ [16 17 9 19]
1246
+
1247
+ sage: E = elementary_matrix(QQ, 4, col1=2, col2=1, scale=10); E
1248
+ [ 1 0 0 0]
1249
+ [ 0 1 10 0]
1250
+ [ 0 0 1 0]
1251
+ [ 0 0 0 1]
1252
+ sage: A*E
1253
+ [ 0 1 12 3]
1254
+ [ 4 5 56 7]
1255
+ [ 8 9 100 11]
1256
+ [ 12 13 144 15]
1257
+ [ 16 17 188 19]
1258
+
1259
+ An elementary matrix is always nonsingular. Then repeated row
1260
+ operations can be represented by products of elementary matrices,
1261
+ and this product is again nonsingular. If row operations are to
1262
+ preserve fundamental properties of a matrix (like rank), we do not
1263
+ allow scaling a row by zero. Similarly, the corresponding elementary
1264
+ matrix is not constructed. Also, we do not allow adding a multiple
1265
+ of a row to itself, since this could also lead to a new zero row. ::
1266
+
1267
+ sage: A = matrix(QQ, 4, 10, range(40)); A
1268
+ [ 0 1 2 3 4 5 6 7 8 9]
1269
+ [10 11 12 13 14 15 16 17 18 19]
1270
+ [20 21 22 23 24 25 26 27 28 29]
1271
+ [30 31 32 33 34 35 36 37 38 39]
1272
+
1273
+ sage: E1 = elementary_matrix(QQ, 4, row1=0, row2=1)
1274
+ sage: E2 = elementary_matrix(QQ, 4, row1=3, row2=0, scale=100)
1275
+ sage: E = E2*E1
1276
+ sage: E.is_singular()
1277
+ False
1278
+ sage: E*A
1279
+ [ 10 11 12 13 14 15 16 17 18 19]
1280
+ [ 0 1 2 3 4 5 6 7 8 9]
1281
+ [ 20 21 22 23 24 25 26 27 28 29]
1282
+ [1030 1131 1232 1333 1434 1535 1636 1737 1838 1939]
1283
+
1284
+ sage: E3 = elementary_matrix(QQ, 4, row1=3, scale=0)
1285
+ Traceback (most recent call last):
1286
+ ...
1287
+ ValueError: scale parameter of row of elementary matrix must be nonzero
1288
+
1289
+ sage: E4 = elementary_matrix(QQ, 4, row1=3, row2=3, scale=12)
1290
+ Traceback (most recent call last):
1291
+ ...
1292
+ ValueError: cannot add a multiple of a row to itself
1293
+
1294
+ If the ring is not specified, and a scale parameter is given, the
1295
+ base ring for the matrix is chosen to contain the scale parameter.
1296
+ Otherwise, if no ring is given, the default is the integers. ::
1297
+
1298
+ sage: E = elementary_matrix(4, row1=1, row2=3)
1299
+ sage: E.parent()
1300
+ Full MatrixSpace of 4 by 4 dense matrices over Integer Ring
1301
+
1302
+ sage: E = elementary_matrix(4, row1=1, scale=4/3)
1303
+ sage: E.parent()
1304
+ Full MatrixSpace of 4 by 4 dense matrices over Rational Field
1305
+
1306
+ sage: # needs sage.symbolic
1307
+ sage: E = elementary_matrix(4, row1=1, scale=I)
1308
+ sage: E.parent()
1309
+ Full MatrixSpace of 4 by 4 dense matrices over
1310
+ Number Field in I with defining polynomial x^2 + 1 with I = 1*I
1311
+
1312
+ sage: # needs sage.rings.complex_double sage.symbolic
1313
+ sage: E = elementary_matrix(4, row1=1, scale=CDF(I))
1314
+ sage: E.parent()
1315
+ Full MatrixSpace of 4 by 4 dense matrices over Complex Double Field
1316
+
1317
+ sage: # needs sage.rings.number_field sage.symbolic
1318
+ sage: E = elementary_matrix(4, row1=1, scale=QQbar(I))
1319
+ sage: E.parent()
1320
+ Full MatrixSpace of 4 by 4 dense matrices over Algebraic Field
1321
+
1322
+ Returned matrices have a dense implementation by default,
1323
+ but a sparse implementation may be requested. ::
1324
+
1325
+ sage: E = elementary_matrix(4, row1=0, row2=1)
1326
+ sage: E.is_dense()
1327
+ True
1328
+
1329
+ sage: E = elementary_matrix(4, row1=0, row2=1, sparse=True)
1330
+ sage: E.is_sparse()
1331
+ True
1332
+
1333
+ And the ridiculously small cases. The zero-row matrix cannot be built
1334
+ since then there are no rows to manipulate. ::
1335
+
1336
+ sage: elementary_matrix(QQ, 1, row1=0, row2=0)
1337
+ [1]
1338
+ sage: elementary_matrix(QQ, 0, row1=0, row2=0)
1339
+ Traceback (most recent call last):
1340
+ ...
1341
+ ValueError: size of elementary matrix must be 1 or greater, not 0
1342
+
1343
+ TESTS::
1344
+
1345
+ sage: E = elementary_matrix('junk', 5, row1=3, row2=1, scale=12)
1346
+ Traceback (most recent call last):
1347
+ ...
1348
+ TypeError: optional first parameter must be a ring, not junk
1349
+
1350
+ sage: E = elementary_matrix(5, row1=3, scale='junk')
1351
+ Traceback (most recent call last):
1352
+ ...
1353
+ TypeError: scale must be an element of some ring, not junk
1354
+
1355
+ sage: E = elementary_matrix(ZZ, 5, row1=3, col2=3, scale=12)
1356
+ Traceback (most recent call last):
1357
+ ...
1358
+ ValueError: received an unexpected keyword: col2=3
1359
+
1360
+ sage: E = elementary_matrix(QQ, row1=3, scale=12)
1361
+ Traceback (most recent call last):
1362
+ ...
1363
+ ValueError: size of elementary matrix must be given
1364
+
1365
+ sage: E = elementary_matrix(ZZ, 4/3, row1=3, row2=1, scale=12)
1366
+ Traceback (most recent call last):
1367
+ ...
1368
+ TypeError: size of elementary matrix must be an integer, not 4/3
1369
+
1370
+ sage: E = elementary_matrix(ZZ, -3, row1=3, row2=1, scale=12)
1371
+ Traceback (most recent call last):
1372
+ ...
1373
+ ValueError: size of elementary matrix must be 1 or greater, not -3
1374
+
1375
+ sage: E = elementary_matrix(ZZ, 5, row2=1, scale=12)
1376
+ Traceback (most recent call last):
1377
+ ...
1378
+ ValueError: row1 or col1 must be specified
1379
+
1380
+ sage: E = elementary_matrix(ZZ, 5, row1=3, col1=3, scale=12)
1381
+ Traceback (most recent call last):
1382
+ ...
1383
+ ValueError: cannot specify both row1 and col1
1384
+
1385
+ sage: E = elementary_matrix(ZZ, 5, row1=4/3, row2=1, scale=12)
1386
+ Traceback (most recent call last):
1387
+ ...
1388
+ TypeError: row of elementary matrix must be an integer, not 4/3
1389
+
1390
+ sage: E = elementary_matrix(ZZ, 5, col1=5, col2=1, scale=12)
1391
+ Traceback (most recent call last):
1392
+ ...
1393
+ ValueError: column of elementary matrix must be positive and smaller than 5, not 5
1394
+
1395
+ sage: E = elementary_matrix(ZZ, 5, col1=3, col2=4/3, scale=12)
1396
+ Traceback (most recent call last):
1397
+ ...
1398
+ TypeError: column of elementary matrix must be an integer, not 4/3
1399
+
1400
+ sage: E = elementary_matrix(ZZ, 5, row1=3, row2=-1, scale=12)
1401
+ Traceback (most recent call last):
1402
+ ...
1403
+ ValueError: row of elementary matrix must be positive and smaller than 5, not -1
1404
+
1405
+ sage: E = elementary_matrix(ZZ, 5, row1=3, row2=1, scale=4/3)
1406
+ Traceback (most recent call last):
1407
+ ...
1408
+ TypeError: scale parameter of elementary matrix must an element of Integer Ring, not 4/3
1409
+
1410
+ sage: E = elementary_matrix(ZZ, 5, row1=3)
1411
+ Traceback (most recent call last):
1412
+ ...
1413
+ ValueError: insufficient parameters provided to construct elementary matrix
1414
+
1415
+ sage: E = elementary_matrix(ZZ, 5, row1=3, row2=3, scale=12)
1416
+ Traceback (most recent call last):
1417
+ ...
1418
+ ValueError: cannot add a multiple of a row to itself
1419
+
1420
+ sage: E = elementary_matrix(ZZ, 5, col1=3, scale=0)
1421
+ Traceback (most recent call last):
1422
+ ...
1423
+ ValueError: scale parameter of column of elementary matrix must be nonzero
1424
+
1425
+ AUTHOR:
1426
+
1427
+ - Rob Beezer (2011-03-04)
1428
+ """
1429
+ # determine ring and matrix size
1430
+ if arg1 is not None and arg0 not in Rings():
1431
+ raise TypeError('optional first parameter must be a ring, not {0}'.format(arg0))
1432
+ scale = kwds.pop('scale', None)
1433
+ if arg0 in Rings():
1434
+ R = arg0
1435
+ arg0 = arg1
1436
+ elif scale is not None:
1437
+ if not isinstance(scale, RingElement):
1438
+ raise TypeError('scale must be an element of some ring, not {0}'.format(scale))
1439
+ R = scale.parent()
1440
+ else:
1441
+ R = ZZ
1442
+ if arg0 is None:
1443
+ raise ValueError('size of elementary matrix must be given')
1444
+ try:
1445
+ n = Integer(arg0)
1446
+ except TypeError:
1447
+ raise TypeError('size of elementary matrix must be an integer, not {0}'.format(arg0))
1448
+ if n <= 0:
1449
+ raise ValueError('size of elementary matrix must be 1 or greater, not {0}'.format(n))
1450
+ # row operations or column operations?
1451
+ # column operation matrix will be transpose of a row operation matrix
1452
+ row1 = kwds.pop('row1', None)
1453
+ col1 = kwds.pop('col1', None)
1454
+ if row1 is None and col1 is None:
1455
+ raise ValueError('row1 or col1 must be specified')
1456
+ if row1 is not None and col1 is not None:
1457
+ raise ValueError('cannot specify both row1 and col1')
1458
+ rowop = row1 is not None
1459
+ if rowop:
1460
+ opstring = "row"
1461
+ row2 = kwds.pop('row2', None)
1462
+ else:
1463
+ opstring = "column"
1464
+ row1 = col1
1465
+ row2 = kwds.pop('col2', None)
1466
+ sparse = kwds.pop('sparse', False)
1467
+ if kwds:
1468
+ extra = kwds.popitem()
1469
+ raise ValueError('received an unexpected keyword: {0}={1}'.format(extra[0], extra[1]))
1470
+
1471
+ # analyze parameters to determine matrix type
1472
+ try:
1473
+ row1 = Integer(row1)
1474
+ except TypeError:
1475
+ raise TypeError('{0} of elementary matrix must be an integer, not {1}'.format(opstring, row1))
1476
+ if row1 < 0 or row1 >= n:
1477
+ raise ValueError('{0} of elementary matrix must be positive and smaller than {1}, not {2}'.format(opstring, n, row1))
1478
+ if row2 is not None:
1479
+ try:
1480
+ row2 = Integer(row2)
1481
+ except TypeError:
1482
+ raise TypeError('{0} of elementary matrix must be an integer, not {1}'.format(opstring, row2))
1483
+ if row2 < 0 or row2 >= n:
1484
+ raise ValueError('{0} of elementary matrix must be positive and smaller than {1}, not {2}'.format(opstring, n, row2))
1485
+ if scale is not None:
1486
+ try:
1487
+ scale = R(scale)
1488
+ except Exception:
1489
+ raise TypeError('scale parameter of elementary matrix must an element of {0}, not {1}'.format(R, scale))
1490
+
1491
+ # determine type of matrix and adjust an identity matrix
1492
+ # return row operation matrix or the transpose as a column operation matrix
1493
+ elem = identity_matrix(R, n, sparse=sparse)
1494
+ if row2 is None and scale is None:
1495
+ raise ValueError('insufficient parameters provided to construct elementary matrix')
1496
+ elif row2 is not None and scale is not None:
1497
+ if row1 == row2:
1498
+ raise ValueError('cannot add a multiple of a {0} to itself'.format(opstring))
1499
+ elem[row1, row2] = scale
1500
+ elif row2 is not None and scale is None:
1501
+ elem[row1, row1] = 0
1502
+ elem[row2, row2] = 0
1503
+ elem[row1, row2] = 1
1504
+ elem[row2, row1] = 1
1505
+ elif row2 is None and scale is not None:
1506
+ if scale == 0:
1507
+ raise ValueError('scale parameter of {0} of elementary matrix must be nonzero'.format(opstring))
1508
+ elem[row1, row1] = scale
1509
+ if rowop:
1510
+ return elem
1511
+ else:
1512
+ return elem.transpose()
1513
+
1514
+
1515
+ @matrix_method
1516
+ def circulant(v, sparse=None):
1517
+ r"""
1518
+ Return the circulant matrix specified by its 1st row `v`.
1519
+
1520
+ A circulant `n \times n` matrix specified by the 1st row `v=(v_0...v_{n-1})` is
1521
+ the matrix `(c_{ij})_{0 \leq i,j\leq n-1}`, where `c_{ij}=v_{j-i \mod b}`.
1522
+
1523
+ INPUT:
1524
+
1525
+ - ``v`` -- list or a vector of values
1526
+
1527
+ - ``sparse`` -- ``None`` by default; if ``sparse`` is set to ``True``, the output
1528
+ will be sparse. Respectively, setting it to ``False`` produces dense output.
1529
+ If ``sparse`` is not set, and if ``v`` is a vector, the output sparsity is determined
1530
+ by the sparsity of ``v``; else, the output will be dense.
1531
+
1532
+ EXAMPLES::
1533
+
1534
+ sage: v = [1,2,3,4,8]
1535
+ sage: matrix.circulant(v)
1536
+ [1 2 3 4 8]
1537
+ [8 1 2 3 4]
1538
+ [4 8 1 2 3]
1539
+ [3 4 8 1 2]
1540
+ [2 3 4 8 1]
1541
+ sage: m = matrix.circulant(vector(GF(3),[0,1,-1],sparse=True)); m
1542
+ [0 1 2]
1543
+ [2 0 1]
1544
+ [1 2 0]
1545
+ sage: m.is_sparse()
1546
+ True
1547
+
1548
+ TESTS::
1549
+
1550
+ sage: m = matrix.circulant(vector(GF(3),[0,1,-1],sparse=False))
1551
+ sage: m.is_sparse()
1552
+ False
1553
+ sage: matrix.circulant([0,1,-1]).is_sparse()
1554
+ False
1555
+ sage: matrix.circulant([0,1,-1], sparse=True).is_sparse()
1556
+ True
1557
+ """
1558
+ if sparse is None:
1559
+ try:
1560
+ sparse = v.is_sparse()
1561
+ except AttributeError:
1562
+ sparse = False
1563
+ n = len(v)
1564
+ return matrix(n, n, lambda i, j: v[(j - i) % n], sparse=sparse)
1565
+
1566
+
1567
+ def _determine_block_matrix_grid(sub_matrices):
1568
+ r"""
1569
+ For internal use. This tries to determine the dimensions
1570
+ of rows/columns when assembling the matrices in sub_matrices in a
1571
+ rectangular grid. It returns a pair of lists containing
1572
+ respectively the sizes of rows and columns.
1573
+
1574
+ sub_matrices must be a list of lists of matrices. All sublists
1575
+ are expected to be the same size.
1576
+
1577
+ Non-zero scalars are considered to be square matrices of any size,
1578
+ and zeroes are considered to be zero matrices of any size.
1579
+
1580
+ A :exc:`ValueError` is raised if there is insufficient or
1581
+ conflicting information.
1582
+
1583
+ TESTS::
1584
+
1585
+ sage: from sage.matrix.special import _determine_block_matrix_grid
1586
+ sage: A = matrix(QQ, 2, 2, [3,9,6,10])
1587
+ sage: _determine_block_matrix_grid([[A, A], [A, A]])
1588
+ ([2, 2], [2, 2])
1589
+
1590
+ sage: B = matrix(QQ, 1, 1, [ 1 ] )
1591
+ sage: C = matrix(QQ, 2, 2, [ 2, 3, 4, 5 ] )
1592
+ sage: _determine_block_matrix_grid([[B, 0], [0, C]])
1593
+ ([1, 2], [1, 2])
1594
+ """
1595
+
1596
+ nrows = len(sub_matrices)
1597
+ if nrows == 0:
1598
+ return ([], [])
1599
+ ncols = len(sub_matrices[0])
1600
+
1601
+ if ncols == 0:
1602
+ return ([0] * nrows, [])
1603
+
1604
+ row_heights = [None] * nrows
1605
+ col_widths = [None] * ncols
1606
+
1607
+ changing = True
1608
+ while changing:
1609
+ changing = False
1610
+ for i in range(nrows):
1611
+ for j in range(ncols):
1612
+ M = sub_matrices[i][j]
1613
+ sub_width = None
1614
+ sub_height = None
1615
+ if isinstance(M, Matrix):
1616
+ sub_width = M.ncols()
1617
+ sub_height = M.nrows()
1618
+ elif M: # nonzero scalar is interpreted as a square matrix
1619
+ if row_heights[i] is None:
1620
+ sub_width = col_widths[j]
1621
+ else:
1622
+ sub_width = row_heights[i]
1623
+ sub_height = sub_width
1624
+ if sub_width is not None:
1625
+ if col_widths[j] is None:
1626
+ changing = True
1627
+ col_widths[j] = sub_width
1628
+ elif col_widths[j] != sub_width:
1629
+ raise ValueError("incompatible submatrix widths")
1630
+ if sub_height is not None:
1631
+ if row_heights[i] is None:
1632
+ changing = True
1633
+ row_heights[i] = sub_height
1634
+ elif row_heights[i] != sub_height:
1635
+ raise ValueError("incompatible submatrix heights")
1636
+
1637
+ if None in row_heights or None in col_widths:
1638
+ if None in row_heights or None in col_widths:
1639
+ raise ValueError("insufficient information to determine dimensions.")
1640
+
1641
+ return (row_heights, col_widths)
1642
+
1643
+
1644
+ def _determine_block_matrix_rows(sub_matrices):
1645
+ """
1646
+ For internal use. This tests if the matrices in sub_matrices
1647
+ fit in a rectangular matrix when assembled a row at a time.
1648
+
1649
+ sub_matrices must be a list of lists of matrices.
1650
+
1651
+ It returns a pair (row_heights, zero_widths, width) where
1652
+ row_heights is the list of row heights, zero_widths is the
1653
+ total width filled up by zero matrices per row, and width
1654
+ is the total width of the resulting matrix.
1655
+
1656
+ Non-zero scalars are considered to be square matrices of any size,
1657
+ and zeroes are considered to be zero matrices of any size.
1658
+
1659
+ A :exc:`ValueError` is raised if there is insufficient or
1660
+ conflicting information.
1661
+
1662
+ TESTS::
1663
+
1664
+ sage: from sage.matrix.special import _determine_block_matrix_rows
1665
+ sage: A = Matrix(ZZ, 1, 4, [1, 2, 3, 4])
1666
+ sage: _determine_block_matrix_rows([ [1, 1], [ A ] ])
1667
+ ([2, 1], [0, 0], 4)
1668
+
1669
+ sage: B = Matrix(ZZ, 2, 2, [1, 2, 3, 4])
1670
+ sage: _determine_block_matrix_rows([ [B, B], [B, 1] ])
1671
+ ([2, 2], [0, 0], 4)
1672
+ """
1673
+ total_width = None
1674
+ row_heights = [None] * len(sub_matrices)
1675
+ zero_widths = [0] * len(sub_matrices)
1676
+
1677
+ # We first do a pass to see if we can determine the width
1678
+ unknowns = False
1679
+ for i in range(len(sub_matrices)):
1680
+ R = sub_matrices[i]
1681
+ height = None
1682
+ # We first do a pass to see if we can determine the height
1683
+ # of this row
1684
+ found_zeroes = False
1685
+ for M in R:
1686
+ if isinstance(M, Matrix):
1687
+ if height is None:
1688
+ height = M.nrows()
1689
+ elif height != M.nrows():
1690
+ raise ValueError("incompatible submatrix heights")
1691
+ elif not M:
1692
+ found_zeroes = True
1693
+ if not R:
1694
+ height = 0
1695
+
1696
+ # If we have a height, then we know the dimensions of any
1697
+ # nonzero scalars, and can maybe compute the width
1698
+ if height is not None and not found_zeroes:
1699
+ width = 0
1700
+ for M in R:
1701
+ if isinstance(M, Matrix):
1702
+ width += M.ncols()
1703
+ else:
1704
+ # nonzero scalar
1705
+ width += height
1706
+ if total_width is None:
1707
+ total_width = width
1708
+ elif total_width != width:
1709
+ raise ValueError("incompatible submatrix widths")
1710
+ row_heights[i] = height
1711
+ else:
1712
+ # We don't set height here even if we know it,
1713
+ # to signal this row hasn't been fit yet.
1714
+ unknowns = True
1715
+
1716
+ if total_width is None:
1717
+ raise ValueError("insufficient information to determine submatrix widths")
1718
+
1719
+ if unknowns:
1720
+ # Do a second pass and see if the remaining rows can be
1721
+ # determined now that we know the width of the matrix.
1722
+ for i in range(len(sub_matrices)):
1723
+ if row_heights[i] is not None:
1724
+ continue
1725
+ R = sub_matrices[i]
1726
+ zero_state = 0
1727
+ # 0: no zeroes found
1728
+ # 1: consecutive zeroes found
1729
+ # 2: consecutive zeroes followed by nonzero found
1730
+ # 3: non-consecutive zeroes found
1731
+ scalars = 0
1732
+ width = 0
1733
+ height = None
1734
+ for j in range(len(R)):
1735
+ M = R[j]
1736
+ if isinstance(M, Matrix):
1737
+ height = M.nrows()
1738
+ width += M.ncols()
1739
+ if zero_state == 1:
1740
+ zero_state = 2
1741
+ elif not M:
1742
+ if zero_state == 0:
1743
+ zero_state = 1
1744
+ elif zero_state == 2:
1745
+ zero_state = 3
1746
+ else:
1747
+ scalars += 1
1748
+
1749
+ remaining_width = total_width - width
1750
+ # This remaining width has to be split over the
1751
+ # zeroes and (nonzero) scalars
1752
+
1753
+ if height is not None:
1754
+ remaining_width -= scalars * height
1755
+ if remaining_width < 0:
1756
+ raise ValueError("incompatible submatrix widths")
1757
+ if remaining_width > 0 and zero_state == 3:
1758
+ raise ValueError("insufficient information to determine submatrix widths")
1759
+ if remaining_width > 0 and zero_state == 0:
1760
+ raise ValueError("incompatible submatrix widths")
1761
+ # otherwise, things fit
1762
+ row_heights[i] = height
1763
+ zero_widths[i] = remaining_width
1764
+ elif zero_state != 0:
1765
+ # if we don't know the height, and there are zeroes,
1766
+ # we can't determine the height
1767
+ raise ValueError("insufficient information to determine submatrix heights")
1768
+ elif total_width % len(R):
1769
+ raise ValueError("incompatible submatrix widths")
1770
+ else:
1771
+ height = int(total_width / len(R))
1772
+ row_heights[i] = height
1773
+
1774
+ # If we got this far, then everything fits
1775
+ return (row_heights, zero_widths, total_width)
1776
+
1777
+
1778
+ @matrix_method
1779
+ def block_matrix(*args, **kwds):
1780
+ r"""
1781
+ Return a larger matrix made by concatenating submatrices
1782
+ (rows first, then columns). For example, the matrix
1783
+
1784
+ ::
1785
+
1786
+ [ A B ]
1787
+ [ C D ]
1788
+
1789
+ is made up of submatrices A, B, C, and D.
1790
+
1791
+ INPUT:
1792
+
1793
+ The block_matrix command takes a list of submatrices to add
1794
+ as blocks, optionally preceded by a ring and the number of block rows
1795
+ and block columns, and returns a matrix.
1796
+
1797
+ The submatrices can be specified as a list of matrices (using
1798
+ ``nrows`` and ``ncols`` to determine their layout), or a list
1799
+ of lists of matrices, where each list forms a row.
1800
+
1801
+ - ``ring`` -- the base ring
1802
+
1803
+ - ``nrows`` -- the number of block rows
1804
+
1805
+ - ``ncols`` -- the number of block cols
1806
+
1807
+ - ``sub_matrices`` -- matrices (see below for syntax)
1808
+
1809
+ - ``subdivide`` -- boolean, whether or not to add
1810
+ subdivision information to the matrix
1811
+
1812
+ - ``sparse`` -- boolean, whether to make the resulting matrix sparse
1813
+
1814
+ EXAMPLES::
1815
+
1816
+ sage: A = matrix(QQ, 2, 2, [3,9,6,10])
1817
+ sage: block_matrix([ [A, -A], [~A, 100*A] ])
1818
+ [ 3 9| -3 -9]
1819
+ [ 6 10| -6 -10]
1820
+ [-----------+-----------]
1821
+ [-5/12 3/8| 300 900]
1822
+ [ 1/4 -1/8| 600 1000]
1823
+
1824
+ If the number of submatrices in each row is the same,
1825
+ you can specify the submatrices as a single list too::
1826
+
1827
+ sage: block_matrix(2, 2, [ A, A, A, A ])
1828
+ [ 3 9| 3 9]
1829
+ [ 6 10| 6 10]
1830
+ [-----+-----]
1831
+ [ 3 9| 3 9]
1832
+ [ 6 10| 6 10]
1833
+
1834
+ One can use constant entries::
1835
+
1836
+ sage: block_matrix([ [1, A], [0, 1] ])
1837
+ [ 1 0| 3 9]
1838
+ [ 0 1| 6 10]
1839
+ [-----+-----]
1840
+ [ 0 0| 1 0]
1841
+ [ 0 0| 0 1]
1842
+
1843
+ A zero entry may represent any square or non-square zero matrix::
1844
+
1845
+ sage: B = matrix(QQ, 1, 1, [ 1 ] )
1846
+ sage: C = matrix(QQ, 2, 2, [ 2, 3, 4, 5 ] )
1847
+ sage: block_matrix([ [B, 0], [0, C] ])
1848
+ [1|0 0]
1849
+ [-+---]
1850
+ [0|2 3]
1851
+ [0|4 5]
1852
+
1853
+ One can specify the number of rows or columns as keywords too::
1854
+
1855
+ sage: block_matrix([A, -A, ~A, 100*A], ncols=4)
1856
+ [ 3 9| -3 -9|-5/12 3/8| 300 900]
1857
+ [ 6 10| -6 -10| 1/4 -1/8| 600 1000]
1858
+
1859
+ sage: block_matrix([A, -A, ~A, 100*A], nrows=1)
1860
+ [ 3 9| -3 -9|-5/12 3/8| 300 900]
1861
+ [ 6 10| -6 -10| 1/4 -1/8| 600 1000]
1862
+
1863
+ It handles base rings nicely too::
1864
+
1865
+ sage: R.<x> = ZZ['x']
1866
+ sage: block_matrix(2, 2, [1/2, A, 0, x-1])
1867
+ [ 1/2 0| 3 9]
1868
+ [ 0 1/2| 6 10]
1869
+ [-----------+-----------]
1870
+ [ 0 0|x - 1 0]
1871
+ [ 0 0| 0 x - 1]
1872
+
1873
+ sage: block_matrix(2, 2, [1/2, A, 0, x-1]).parent()
1874
+ Full MatrixSpace of 4 by 4 dense matrices over Univariate Polynomial Ring in x over Rational Field
1875
+
1876
+ Subdivisions are optional. If they are disabled, the columns need not line up::
1877
+
1878
+ sage: B = matrix(QQ, 2, 3, range(6))
1879
+ sage: block_matrix([ [~A, B], [B, ~A] ], subdivide=False)
1880
+ [-5/12 3/8 0 1 2]
1881
+ [ 1/4 -1/8 3 4 5]
1882
+ [ 0 1 2 -5/12 3/8]
1883
+ [ 3 4 5 1/4 -1/8]
1884
+
1885
+ Without subdivisions it also deduces dimensions for scalars if possible::
1886
+
1887
+ sage: C = matrix(ZZ, 1, 2, range(2))
1888
+ sage: block_matrix([ [ C, 0 ], [ 3, 4 ], [ 5, 6, C ] ], subdivide=False )
1889
+ [0 1 0 0]
1890
+ [3 0 4 0]
1891
+ [0 3 0 4]
1892
+ [5 6 0 1]
1893
+
1894
+ If all submatrices are sparse (unless there are none at all), the result
1895
+ will be a sparse matrix. Otherwise it will be dense by default. The
1896
+ ``sparse`` keyword can be used to override this::
1897
+
1898
+ sage: A = Matrix(ZZ, 2, 2, [0, 1, 0, 0], sparse=True)
1899
+ sage: block_matrix([ [ A ], [ A ] ]).parent()
1900
+ Full MatrixSpace of 4 by 2 sparse matrices over Integer Ring
1901
+ sage: block_matrix([ [ A ], [ A ] ], sparse=False).parent()
1902
+ Full MatrixSpace of 4 by 2 dense matrices over Integer Ring
1903
+
1904
+ Consecutive zero submatrices are consolidated. ::
1905
+
1906
+ sage: B = matrix(2, range(4))
1907
+ sage: C = matrix(2, 8, range(16))
1908
+ sage: block_matrix(2, [[B,0,0,B],[C]], subdivide=False)
1909
+ [ 0 1 0 0 0 0 0 1]
1910
+ [ 2 3 0 0 0 0 2 3]
1911
+ [ 0 1 2 3 4 5 6 7]
1912
+ [ 8 9 10 11 12 13 14 15]
1913
+
1914
+ Ambiguity is not tolerated. ::
1915
+
1916
+ sage: B = matrix(2, range(4))
1917
+ sage: C = matrix(2, 8, range(16))
1918
+ sage: block_matrix(2, [[B,0,B,0],[C]], subdivide=False)
1919
+ Traceback (most recent call last):
1920
+ ...
1921
+ ValueError: insufficient information to determine submatrix widths
1922
+
1923
+ Giving only a flat list of submatrices does not work::
1924
+
1925
+ sage: A = matrix(2, 3, range(6))
1926
+ sage: B = matrix(3, 3, range(9))
1927
+ sage: block_matrix([A, A, B, B])
1928
+ Traceback (most recent call last):
1929
+ ...
1930
+ ValueError: must specify either nrows or ncols
1931
+
1932
+ TESTS::
1933
+
1934
+ sage: A = matrix(ZZ, 2, 2, [3,5,8,13])
1935
+ sage: block_matrix(A)
1936
+ [ 3 5]
1937
+ [ 8 13]
1938
+ sage: block_matrix([[A, 0r], [1r, A]])
1939
+ [ 3 5| 0 0]
1940
+ [ 8 13| 0 0]
1941
+ [-----+-----]
1942
+ [ 1 0| 3 5]
1943
+ [ 0 1| 8 13]
1944
+ """
1945
+ args = list(args)
1946
+ sparse = kwds.get('sparse', None)
1947
+
1948
+ if not args:
1949
+ if sparse is not None:
1950
+ return matrix_space.MatrixSpace(ZZ, 0, 0, sparse=sparse)([])
1951
+ else:
1952
+ return matrix_space.MatrixSpace(ZZ, 0, 0)([])
1953
+
1954
+ if len(args) >= 1 and args[0] in Rings():
1955
+ # A ring is specified
1956
+ if kwds.get('ring', args[0]) != args[0]:
1957
+ raise ValueError("base ring specified twice and they are different")
1958
+ ring = args[0]
1959
+ args.pop(0)
1960
+ else:
1961
+ ring = kwds.get('ring', None)
1962
+
1963
+ if len(args) >= 1:
1964
+ try:
1965
+ nrows = int(args[0])
1966
+ args.pop(0)
1967
+ if kwds.get('nrows', nrows) != nrows:
1968
+ raise ValueError("number of rows specified twice and they are different")
1969
+ except TypeError:
1970
+ nrows = kwds.get('nrows', None)
1971
+ else:
1972
+ nrows = kwds.get('nrows', None)
1973
+
1974
+ if len(args) >= 1:
1975
+ # check to see if additionally, the number of columns is specified
1976
+ try:
1977
+ ncols = int(args[0])
1978
+ args.pop(0)
1979
+ if kwds.get('ncols', ncols) != ncols:
1980
+ raise ValueError("number of columns specified twice and they are different")
1981
+ except TypeError:
1982
+ ncols = kwds.get('ncols', None)
1983
+ else:
1984
+ ncols = kwds.get('ncols', None)
1985
+
1986
+ # Now we've taken care of initial ring, nrows, and ncols arguments.
1987
+
1988
+ # Now the rest of the arguments are a list of rows, a flat list of
1989
+ # matrices, or a single value.
1990
+
1991
+ if not args:
1992
+ args = [[]]
1993
+ if len(args) > 1:
1994
+ print(args)
1995
+ raise TypeError("invalid block_matrix invocation")
1996
+
1997
+ sub_matrices = args[0]
1998
+
1999
+ if isinstance(sub_matrices, Matrix):
2000
+ M = sub_matrices
2001
+ # a single matrix (check nrows/ncols/ring)
2002
+ if (nrows is not None and nrows != 1) or \
2003
+ (ncols is not None and ncols != 1):
2004
+ raise ValueError("invalid nrows/ncols passed to block_matrix")
2005
+ if ring is not None:
2006
+ M = M.change_ring(ring)
2007
+ if sparse is not None and M.is_sparse() != sparse:
2008
+ M = M.sparse_matrix() if sparse else M.dense_matrix()
2009
+ return M
2010
+
2011
+ if not isinstance(sub_matrices, (list, tuple)):
2012
+ raise TypeError("invalid block_matrix invocation")
2013
+
2014
+ subdivide = kwds.get('subdivide', True)
2015
+
2016
+ # Will we try to place the matrices in a rectangular grid?
2017
+ try_grid = True
2018
+
2019
+ if not sub_matrices:
2020
+ if (nrows is not None and nrows != 0) or \
2021
+ (ncols is not None and ncols != 0):
2022
+ raise ValueError("invalid nrows/ncols passed to block_matrix")
2023
+ elif isinstance(sub_matrices[0], (list, tuple)):
2024
+ # A list of lists: verify all elements are lists, and if
2025
+ # ncols is set, the lengths match.
2026
+ if nrows is not None and len(sub_matrices) != nrows:
2027
+ raise ValueError("invalid nrows passed to block_matrix")
2028
+ first_len = len(sub_matrices[0])
2029
+ if ncols is not None and first_len != ncols:
2030
+ raise ValueError("invalid ncols passed to block_matrix")
2031
+ same_length = all(isinstance(v, (list, tuple)) and len(v) == first_len for v in sub_matrices)
2032
+ if subdivide and not same_length:
2033
+ raise ValueError("list of rows is not valid (rows are wrong types or lengths)")
2034
+ try_grid = same_length
2035
+ else:
2036
+ # A flat list
2037
+ # determine the block dimensions
2038
+ n = len(sub_matrices)
2039
+ if nrows is None:
2040
+ if ncols is None:
2041
+ raise ValueError("must specify either nrows or ncols")
2042
+ else:
2043
+ nrows = n // ncols
2044
+ elif ncols is None:
2045
+ ncols = n // nrows
2046
+ if nrows * ncols != n:
2047
+ raise ValueError("given number of rows (%s), columns (%s) incompatible with number of submatrices (%s)" % (nrows, ncols, n))
2048
+ # Now create a list of lists from this
2049
+ sub_matrices = [sub_matrices[i * ncols: (i + 1) * ncols]
2050
+ for i in range(nrows)]
2051
+
2052
+ # At this point sub_matrices is a list of lists
2053
+
2054
+ # determine the base ring and sparsity
2055
+ if ring is None:
2056
+ ring = ZZ
2057
+ for row in sub_matrices:
2058
+ for M in row:
2059
+ R = M.base_ring() if isinstance(M, Matrix) else parent(M)
2060
+ if R is not ZZ:
2061
+ ring = sage.categories.pushout.pushout(ring, R)
2062
+
2063
+ if sparse is None:
2064
+ sparse = True
2065
+ for row in sub_matrices:
2066
+ for M in row:
2067
+ if sparse and isinstance(M, Matrix) and not M.is_sparse():
2068
+ sparse = False
2069
+
2070
+ row_heights = None
2071
+ col_widths = None
2072
+ zero_widths = None
2073
+ total_width = None
2074
+
2075
+ # We first try to place the matrices in a rectangular grid
2076
+ if try_grid:
2077
+ try:
2078
+ (row_heights, col_widths) = _determine_block_matrix_grid(sub_matrices)
2079
+ except ValueError as e:
2080
+ if subdivide:
2081
+ raise ValueError(e)
2082
+
2083
+ if col_widths is None:
2084
+ # Try placing the matrices in rows instead
2085
+ # (Only if subdivide is False)
2086
+ (row_heights, zero_widths, total_width) = _determine_block_matrix_rows(sub_matrices)
2087
+
2088
+ # Success, so assemble the final matrix
2089
+
2090
+ big = None
2091
+ for i in range(len(sub_matrices)):
2092
+ R = sub_matrices[i]
2093
+ row = None
2094
+ for j in range(len(R)):
2095
+ M = R[j]
2096
+
2097
+ if isinstance(M, Matrix):
2098
+ if M.base_ring() is not ring:
2099
+ M = M.change_ring(ring)
2100
+ if M.is_sparse() != sparse:
2101
+ M = M.sparse_matrix() if sparse else M.dense_matrix()
2102
+ elif not M and zero_widths is not None:
2103
+ if zero_widths[i] > 0:
2104
+ M = matrix(ring, row_heights[i], zero_widths[i], 0, sparse=sparse)
2105
+ zero_widths[i] = 0
2106
+ else:
2107
+ continue # zero-width matrix
2108
+ else:
2109
+ if zero_widths is not None:
2110
+ M = matrix(ring, row_heights[i], row_heights[i], M, sparse=sparse)
2111
+ else:
2112
+ M = matrix(ring, row_heights[i], col_widths[j], M, sparse=sparse)
2113
+
2114
+ # append M to this row
2115
+ if row is None:
2116
+ row = M
2117
+ else:
2118
+ row = row.augment(M)
2119
+
2120
+ # append row to final matrix
2121
+ if big is None:
2122
+ big = row
2123
+ else:
2124
+ big = big.stack(row)
2125
+
2126
+ if big is None:
2127
+ if ring is None:
2128
+ ring = ZZ
2129
+ big = matrix(ring, 0, 0)
2130
+
2131
+ if subdivide:
2132
+ big.subdivide(running_total(row_heights[:-1]),
2133
+ running_total(col_widths[:-1]))
2134
+
2135
+ return big
2136
+
2137
+
2138
+ @matrix_method
2139
+ def block_diagonal_matrix(*sub_matrices, **kwds):
2140
+ """
2141
+ Create a block matrix whose diagonal block entries are given by
2142
+ sub_matrices, with zero elsewhere.
2143
+
2144
+ See also :meth:`block_matrix`.
2145
+
2146
+ EXAMPLES::
2147
+
2148
+ sage: A = matrix(ZZ, 2, [1,2,3,4])
2149
+ sage: block_diagonal_matrix(A, A)
2150
+ [1 2|0 0]
2151
+ [3 4|0 0]
2152
+ [---+---]
2153
+ [0 0|1 2]
2154
+ [0 0|3 4]
2155
+
2156
+ The sub-matrices need not be square::
2157
+
2158
+ sage: B = matrix(QQ, 2, 3, range(6))
2159
+ sage: block_diagonal_matrix(~A, B)
2160
+ [ -2 1| 0 0 0]
2161
+ [ 3/2 -1/2| 0 0 0]
2162
+ [---------+--------------]
2163
+ [ 0 0| 0 1 2]
2164
+ [ 0 0| 3 4 5]
2165
+ """
2166
+ if isinstance(sub_matrices, (list, tuple)) and len(sub_matrices) == 1:
2167
+ sub_matrices = sub_matrices[0]
2168
+ n = len(sub_matrices)
2169
+ entries = [ZZ.zero()] * n**2
2170
+ for i in range(n):
2171
+ entries[n*i+i] = sub_matrices[i]
2172
+ return block_matrix(n, n, entries, **kwds)
2173
+
2174
+
2175
+ @matrix_method
2176
+ def jordan_block(eigenvalue, size, sparse=False):
2177
+ r"""
2178
+ Return the Jordan block for the given eigenvalue with given size.
2179
+
2180
+ INPUT:
2181
+
2182
+ - ``eigenvalue`` -- eigenvalue for the diagonal entries of the block
2183
+ - ``size`` -- size of the square matrix
2184
+ - ``sparse`` -- (default: ``False``) if ``True``, return a sparse matrix
2185
+
2186
+ EXAMPLES::
2187
+
2188
+ sage: jordan_block(5, 3)
2189
+ [5 1 0]
2190
+ [0 5 1]
2191
+ [0 0 5]
2192
+
2193
+ TESTS::
2194
+
2195
+ sage: jordan_block(6.2, 'junk')
2196
+ Traceback (most recent call last):
2197
+ ...
2198
+ TypeError: size of Jordan block needs to be an integer, not junk
2199
+ sage: jordan_block(6.2, -1)
2200
+ Traceback (most recent call last):
2201
+ ...
2202
+ ValueError: size of Jordan block must be nonnegative, not -1
2203
+ """
2204
+ try:
2205
+ size = ZZ(size)
2206
+ except TypeError:
2207
+ msg = "size of Jordan block needs to be an integer, not {0}"
2208
+ raise TypeError(msg.format(size))
2209
+ if size < 0:
2210
+ msg = "size of Jordan block must be nonnegative, not {0}"
2211
+ raise ValueError(msg.format(size))
2212
+ block = diagonal_matrix([eigenvalue] * size, sparse=sparse)
2213
+ for i in range(size - 1):
2214
+ block[i, i + 1] = 1
2215
+ return block
2216
+
2217
+
2218
+ @matrix_method
2219
+ def companion_matrix(poly, format='right'):
2220
+ r"""
2221
+ Create a companion matrix from a monic polynomial.
2222
+
2223
+ INPUT:
2224
+
2225
+ - ``poly`` -- a univariate polynomial, or an iterable containing
2226
+ the coefficients of a polynomial, with low-degree coefficients first.
2227
+ The polynomial (or the polynomial implied by the coefficients) must
2228
+ be monic. In other words, the leading coefficient must be one.
2229
+ A symbolic expression that might also be a polynomial is not
2230
+ proper input, see examples below.
2231
+
2232
+ - ``format`` -- (default: ``'right'``) specifies one of four
2233
+ variations of a companion matrix. Allowable values are
2234
+ ``'right'``, ``'left'``, ``'top'`` and ``'bottom'``, which indicates
2235
+ which border of the matrix contains the negatives of the coefficients.
2236
+
2237
+ OUTPUT:
2238
+
2239
+ A square matrix with a size equal to the degree of the polynomial.
2240
+ The returned matrix has ones above, or below the diagonal, and the
2241
+ negatives of the coefficients along the indicated border of the
2242
+ matrix (excepting the leading one coefficient).
2243
+ See the first examples below for precise illustrations.
2244
+
2245
+ EXAMPLES:
2246
+
2247
+ Each of the four possibilities. Notice that the coefficients are
2248
+ specified and their negatives become the entries of the matrix. The
2249
+ leading one must be given, but is not used. The permutation matrix
2250
+ ``P`` is the identity matrix, with the columns reversed. The last three
2251
+ statements test the general relationships between the four variants. ::
2252
+
2253
+ sage: poly = [-2, -3, -4, -5, -6, 1]
2254
+ sage: R = companion_matrix(poly, format='right'); R
2255
+ [0 0 0 0 2]
2256
+ [1 0 0 0 3]
2257
+ [0 1 0 0 4]
2258
+ [0 0 1 0 5]
2259
+ [0 0 0 1 6]
2260
+ sage: L = companion_matrix(poly, format='left'); L
2261
+ [6 1 0 0 0]
2262
+ [5 0 1 0 0]
2263
+ [4 0 0 1 0]
2264
+ [3 0 0 0 1]
2265
+ [2 0 0 0 0]
2266
+ sage: B = companion_matrix(poly, format='bottom'); B
2267
+ [0 1 0 0 0]
2268
+ [0 0 1 0 0]
2269
+ [0 0 0 1 0]
2270
+ [0 0 0 0 1]
2271
+ [2 3 4 5 6]
2272
+ sage: T = companion_matrix(poly, format='top'); T
2273
+ [6 5 4 3 2]
2274
+ [1 0 0 0 0]
2275
+ [0 1 0 0 0]
2276
+ [0 0 1 0 0]
2277
+ [0 0 0 1 0]
2278
+
2279
+ sage: perm = Permutation([5, 4, 3, 2, 1])
2280
+ sage: P = perm.to_matrix()
2281
+ sage: L == P*R*P
2282
+ True
2283
+ sage: B == R.transpose()
2284
+ True
2285
+ sage: T == P*R.transpose()*P
2286
+ True
2287
+
2288
+ A polynomial may be used as input, however a symbolic expression,
2289
+ even if it looks like a polynomial, is not regarded as such when used
2290
+ as input to this routine. Obtaining the list of coefficients from a
2291
+ symbolic polynomial is one route to the companion matrix. ::
2292
+
2293
+ sage: x = polygen(QQ, 'x')
2294
+ sage: p = x^3 - 4*x^2 + 8*x - 12
2295
+ sage: companion_matrix(p)
2296
+ [ 0 0 12]
2297
+ [ 1 0 -8]
2298
+ [ 0 1 4]
2299
+
2300
+ sage: # needs sage.symbolic
2301
+ sage: y = var('y')
2302
+ sage: q = y^3 - 2*y + 1
2303
+ sage: companion_matrix(q)
2304
+ Traceback (most recent call last):
2305
+ ...
2306
+ TypeError: input must be a polynomial (not a symbolic expression, see docstring),
2307
+ or other iterable, not y^3 - 2*y + 1
2308
+ sage: coeff_list = [q(y=0)] + [q.coefficient(y^k)
2309
+ ....: for k in range(1, q.degree(y) + 1)]
2310
+ sage: coeff_list
2311
+ [1, -2, 0, 1]
2312
+ sage: companion_matrix(coeff_list)
2313
+ [ 0 0 -1]
2314
+ [ 1 0 2]
2315
+ [ 0 1 0]
2316
+
2317
+ The minimal polynomial of a companion matrix is equal to the
2318
+ polynomial used to create it. Used in a block diagonal
2319
+ construction, they can be used to create matrices with
2320
+ any desired minimal polynomial, or characteristic polynomial. ::
2321
+
2322
+ sage: t = polygen(QQ, 't')
2323
+ sage: p = t^12 - 7*t^4 + 28*t^2 - 456
2324
+ sage: C = companion_matrix(p, format='top')
2325
+ sage: q = C.minpoly(var='t'); q # needs sage.libs.pari
2326
+ t^12 - 7*t^4 + 28*t^2 - 456
2327
+ sage: p == q # needs sage.libs.pari
2328
+ True
2329
+
2330
+ sage: p = t^3 + 3*t - 8
2331
+ sage: q = t^5 + t - 17
2332
+ sage: A = block_diagonal_matrix( companion_matrix(p),
2333
+ ....: companion_matrix(p^2),
2334
+ ....: companion_matrix(q),
2335
+ ....: companion_matrix(q) )
2336
+ sage: A.charpoly(var='t').factor() # needs sage.libs.pari
2337
+ (t^3 + 3*t - 8)^3 * (t^5 + t - 17)^2
2338
+ sage: A.minpoly(var='t').factor() # needs sage.libs.pari
2339
+ (t^3 + 3*t - 8)^2 * (t^5 + t - 17)
2340
+
2341
+ TESTS::
2342
+
2343
+ sage: companion_matrix([4, 5, 1], format='junk')
2344
+ Traceback (most recent call last):
2345
+ ...
2346
+ ValueError: format must be 'right', 'left', 'top' or 'bottom', not junk
2347
+
2348
+ sage: companion_matrix(sin(x)) # needs sage.symbolic
2349
+ Traceback (most recent call last):
2350
+ ...
2351
+ TypeError: input must be a polynomial (not a symbolic expression, see docstring),
2352
+ or other iterable, not sin(x)
2353
+
2354
+ sage: companion_matrix([2, 3, 896])
2355
+ Traceback (most recent call last):
2356
+ ...
2357
+ ValueError: polynomial (or the polynomial implied by coefficients) must be monic,
2358
+ not a leading coefficient of 896
2359
+
2360
+ sage: F.<a> = GF(2^2) # needs sage.rings.finite_rings
2361
+ sage: companion_matrix([4/3, a+1, 1]) # needs sage.rings.finite_rings
2362
+ Traceback (most recent call last):
2363
+ ...
2364
+ TypeError: unable to find common ring for coefficients from polynomial
2365
+
2366
+ sage: A = companion_matrix([1])
2367
+ sage: A.nrows(); A.ncols()
2368
+ 0
2369
+ 0
2370
+
2371
+ sage: A = companion_matrix([])
2372
+ Traceback (most recent call last):
2373
+ ...
2374
+ ValueError: polynomial cannot be specified by an empty list
2375
+
2376
+ sage: companion_matrix([QQ.one()]).parent()
2377
+ Full MatrixSpace of 0 by 0 dense matrices over Rational Field
2378
+
2379
+ AUTHOR:
2380
+
2381
+ - Rob Beezer (2011-05-19)
2382
+ """
2383
+ import sage.matrix.constructor
2384
+ if format not in ['right', 'left', 'top', 'bottom']:
2385
+ raise ValueError("format must be 'right', 'left', 'top' or 'bottom', not {0}".format(format))
2386
+ try:
2387
+ poly = Sequence(poly)
2388
+ except TypeError:
2389
+ raise TypeError('input must be a polynomial (not a symbolic expression, see docstring), or other iterable, not {0}'.format(poly))
2390
+ n = len(poly) - 1
2391
+ if n == -1:
2392
+ raise ValueError('polynomial cannot be specified by an empty list')
2393
+ if not poly[n] == 1:
2394
+ raise ValueError('polynomial (or the polynomial implied by coefficients) must be monic, not a leading coefficient of {0}'.format(poly[n]))
2395
+ try:
2396
+ M = sage.matrix.constructor.matrix(poly.universe(), n, n)
2397
+ except TypeError:
2398
+ raise TypeError("unable to find common ring for coefficients from polynomial")
2399
+ # 1s below diagonal, or above diagonal
2400
+ if format in ['right', 'top']:
2401
+ for i in range(n - 1):
2402
+ M[i+1, i] = 1
2403
+ else:
2404
+ for i in range(n-1):
2405
+ M[i, i+1] = 1
2406
+ # right side, left side (reversed), bottom edge, top edge (reversed)
2407
+ if format == 'right':
2408
+ for i in range(n):
2409
+ M[i, n-1] = -poly[i]
2410
+ elif format == 'left':
2411
+ for i in range(n):
2412
+ M[n-1-i, 0] = -poly[i]
2413
+ elif format == 'bottom':
2414
+ for i in range(n):
2415
+ M[n-1, i] = -poly[i]
2416
+ elif format == 'top':
2417
+ for i in range(n):
2418
+ M[0, n-1-i] = -poly[i]
2419
+ return M
2420
+
2421
+
2422
+ @matrix_method
2423
+ def random_rref_matrix(parent, num_pivots):
2424
+ r"""
2425
+ Generate a matrix in reduced row-echelon form with a specified number of nonzero rows.
2426
+
2427
+ INPUT:
2428
+
2429
+ - ``parent`` -- a matrix space specifying the base ring, dimensions and
2430
+ representation (dense/sparse) for the result. The base ring must be exact.
2431
+
2432
+ - ``num_pivots`` -- the number of nonzero rows in the result, i.e. the rank
2433
+
2434
+ OUTPUT:
2435
+
2436
+ A matrix in reduced row echelon form with ``num_pivots`` nonzero rows. If the
2437
+ base ring is `ZZ` or `QQ` then the entries are all integers.
2438
+
2439
+ .. NOTE::
2440
+
2441
+ It is easiest to use this function via a call to the
2442
+ :func:`~sage.matrix.constructor.random_matrix`
2443
+ function with the ``algorithm='echelon_form'`` keyword. We provide
2444
+ one example accessing this function directly, while the remainder will
2445
+ use this more general function.
2446
+
2447
+ EXAMPLES:
2448
+
2449
+ Matrices generated are in reduced row-echelon form with specified rank. If the
2450
+ base ring is `QQ` the result has only integer entries. ::
2451
+
2452
+ sage: from sage.matrix.constructor import random_rref_matrix
2453
+ sage: matrix_space = sage.matrix.matrix_space.MatrixSpace(QQ, 5, 6)
2454
+ sage: A = random_rref_matrix(matrix_space, num_pivots=4); A # random
2455
+ [ 1 0 0 -6 0 -3]
2456
+ [ 0 1 0 2 0 3]
2457
+ [ 0 0 1 -4 0 -2]
2458
+ [ 0 0 0 0 1 3]
2459
+ [ 0 0 0 0 0 0]
2460
+ sage: A.base_ring()
2461
+ Rational Field
2462
+ sage: (A.nrows(), A.ncols())
2463
+ (5, 6)
2464
+ sage: A in sage.matrix.matrix_space.MatrixSpace(ZZ, 5, 6)
2465
+ True
2466
+ sage: A.rank()
2467
+ 4
2468
+ sage: A == A.rref()
2469
+ True
2470
+
2471
+ Matrices can be generated over other exact rings. ::
2472
+
2473
+ sage: B = random_matrix(FiniteField(7), 4, 4, # random
2474
+ ....: algorithm='echelon_form', num_pivots=3); B
2475
+ [1 0 0 0]
2476
+ [0 1 0 6]
2477
+ [0 0 1 1]
2478
+ [0 0 0 0]
2479
+ sage: B.rank() == 3
2480
+ True
2481
+ sage: B.base_ring()
2482
+ Finite Field of size 7
2483
+ sage: B == B.rref()
2484
+ True
2485
+
2486
+ TESTS:
2487
+
2488
+ Rank zero::
2489
+
2490
+ sage: random_matrix(QQ, 1, 1, algorithm='echelon_form', num_pivots=0)
2491
+ [0]
2492
+
2493
+ Rank of a matrix must be an integer. ::
2494
+
2495
+ sage: random_matrix(QQ, 120, 56, algorithm='echelon_form', num_pivots=61/2)
2496
+ Traceback (most recent call last):
2497
+ ...
2498
+ TypeError: the number of pivots must be an integer
2499
+
2500
+ Matrices must be generated over exact fields. ::
2501
+
2502
+ sage: random_matrix(RR, 40, 88, algorithm='echelon_form', num_pivots=39)
2503
+ Traceback (most recent call last):
2504
+ ...
2505
+ TypeError: the base ring must be exact
2506
+
2507
+ Matrices must have the number of pivot columns be less than or equal to the number of rows. ::
2508
+
2509
+ sage: C = random_matrix(ZZ, 6,4, algorithm='echelon_form', num_pivots=7); C
2510
+ Traceback (most recent call last):
2511
+ ...
2512
+ ValueError: number of pivots cannot exceed the number of rows or columns
2513
+
2514
+ Matrices must have the number of pivot columns be less than or equal to the number of columns. ::
2515
+
2516
+ sage: D = random_matrix(QQ, 1,3, algorithm='echelon_form', num_pivots=5); D
2517
+ Traceback (most recent call last):
2518
+ ...
2519
+ ValueError: number of pivots cannot exceed the number of rows or columns
2520
+
2521
+ Matrices must have the number of pivot columns be greater than zero. ::
2522
+
2523
+ sage: random_matrix(QQ, 5, 4, algorithm='echelon_form', num_pivots=-1)
2524
+ Traceback (most recent call last):
2525
+ ...
2526
+ ValueError: the number of pivots must be zero or greater
2527
+
2528
+ AUTHOR:
2529
+
2530
+ Billy Wonderly (2010-07)
2531
+ """
2532
+ import sage.probability.probability_distribution as pd
2533
+
2534
+ try:
2535
+ num_pivots = ZZ(num_pivots)
2536
+ except TypeError:
2537
+ raise TypeError("the number of pivots must be an integer")
2538
+ if num_pivots < 0:
2539
+ raise ValueError("the number of pivots must be zero or greater")
2540
+ ring = parent.base_ring()
2541
+ if not ring.is_exact():
2542
+ raise TypeError("the base ring must be exact")
2543
+ num_row = parent.nrows()
2544
+ num_col = parent.ncols()
2545
+ if num_pivots > num_row or num_pivots > num_col:
2546
+ raise ValueError("number of pivots cannot exceed the number of rows or columns")
2547
+
2548
+ if num_pivots == 0:
2549
+ return parent.zero()
2550
+
2551
+ one = ring.one()
2552
+ # Create a matrix of the desired size to be modified and then returned.
2553
+ return_matrix = copy(parent.zero_matrix())
2554
+
2555
+ # No harm if no pivots at all.
2556
+ subset = list(range(1, num_col))
2557
+ shuffle(subset)
2558
+ pivots = [0] + sorted(subset[:num_pivots - 1])
2559
+
2560
+ # Use the list of pivot columns to set the pivot entries of the return_matrix to leading ones.
2561
+ for pivot_row, pivot in enumerate(pivots):
2562
+ return_matrix[pivot_row, pivot] = one
2563
+ if ring is QQ or ring is ZZ:
2564
+ # Keep track of the non-pivot columns by using the pivot_index, start at the first column to
2565
+ # the right of the initial pivot column, go until the first column to the left of the next
2566
+ # pivot column.
2567
+ for pivot_index in range(num_pivots - 1):
2568
+ for non_pivot_column_index in range(pivots[pivot_index] + 1, pivots[pivot_index + 1]):
2569
+ entry_generator1 = pd.RealDistribution("beta", [6, 4])
2570
+ # Experimental distribution used to generate the values.
2571
+ for non_pivot_column_entry in range(pivot_index + 1):
2572
+ sign1 = (2 * randint(0, 1) - 1)
2573
+ return_matrix[non_pivot_column_entry, non_pivot_column_index] = sign1 * int(entry_generator1.get_random_element() * ((1 - non_pivot_column_entry / return_matrix.ncols()) * 7))
2574
+ # Use index to fill entries of the columns to the right of the last pivot column.
2575
+ for rest_non_pivot_column in range(pivots[num_pivots - 1] + 1, num_col):
2576
+ entry_generator2 = pd.RealDistribution("beta", [2.6, 4])
2577
+ # experimental distribution to generate small values.
2578
+ for rest_entries in range(num_pivots):
2579
+ sign2 = (2 * randint(0, 1) - 1)
2580
+ return_matrix[rest_entries, rest_non_pivot_column] = sign2 * int(entry_generator2.get_random_element() * 5)
2581
+ else:
2582
+ for pivot_index in range(num_pivots - 1):
2583
+ for non_pivot_column_index in range(pivots[pivot_index] + 1, pivots[pivot_index + 1]):
2584
+ for non_pivot_column_entry in range(pivot_index + 1):
2585
+ return_matrix[non_pivot_column_entry, non_pivot_column_index] = ring.random_element()
2586
+ for rest_non_pivot_column in range(pivots[num_pivots - 1] + 1, num_col):
2587
+ for rest_entries in range(num_pivots):
2588
+ return_matrix[rest_entries, rest_non_pivot_column] = ring.random_element()
2589
+ return return_matrix
2590
+
2591
+
2592
+ @matrix_method
2593
+ def random_echelonizable_matrix(parent, rank, upper_bound=None, max_tries=100):
2594
+ r"""
2595
+ Generate a matrix of a desired size and rank, over a desired ring, whose reduced
2596
+ row-echelon form has only integral values.
2597
+
2598
+ INPUT:
2599
+
2600
+ - ``parent`` -- a matrix space specifying the base ring, dimensions and
2601
+ representation (dense/sparse) for the result. The base ring must be exact.
2602
+
2603
+ - ``rank`` -- rank of result, i.e the number of nonzero rows in the
2604
+ reduced row echelon form
2605
+
2606
+ - ``upper_bound`` -- if designated, size control of the matrix entries is desired
2607
+ Set ``upper_bound`` to 1 more than the maximum value entries can achieve.
2608
+ If ``None``, no size control occurs. But see the warning below. (default: ``None``)
2609
+
2610
+ - ``max_tries`` -- if designated, number of tries used to generate each new random row;s
2611
+ only matters when upper_bound!=None. Used to prevent endless looping. (default: 100)
2612
+
2613
+ OUTPUT: a matrix not in reduced row-echelon form with the desired
2614
+ dimensions and properties
2615
+
2616
+ .. warning::
2617
+
2618
+ When ``upper_bound`` is set, it is possible for this constructor to
2619
+ fail with a :exc:`ValueError`. This may happen when the ``upper_bound``,
2620
+ ``rank`` and/or matrix dimensions are all so small that it becomes
2621
+ infeasible or unlikely to create the requested matrix. If you *must*
2622
+ have this routine return successfully, do not set ``upper_bound``.
2623
+
2624
+ .. NOTE::
2625
+
2626
+ It is easiest to use this function via a call to the
2627
+ :func:`~sage.matrix.constructor.random_matrix`
2628
+ function with the ``algorithm='echelonizable'`` keyword. We provide
2629
+ one example accessing this function directly, while the remainder will
2630
+ use this more general function.
2631
+
2632
+ EXAMPLES:
2633
+
2634
+ Generated matrices have the desired dimensions, rank and entry size. The
2635
+ matrix in reduced row-echelon form has only integer entries. ::
2636
+
2637
+ sage: from sage.matrix.constructor import random_echelonizable_matrix
2638
+ sage: matrix_space = sage.matrix.matrix_space.MatrixSpace(QQ, 5, 6)
2639
+ sage: A = random_echelonizable_matrix(matrix_space, rank=4, upper_bound=40)
2640
+ sage: A.rank()
2641
+ 4
2642
+ sage: max(map(abs,A.list())) < 40
2643
+ True
2644
+ sage: A.rref() == A.rref().change_ring(ZZ)
2645
+ True
2646
+
2647
+ An example with default settings (i.e. no entry size control). ::
2648
+
2649
+ sage: C = random_matrix(QQ, 6, 7, algorithm='echelonizable', rank=5)
2650
+ sage: C.rank()
2651
+ 5
2652
+ sage: C.rref() == C.rref().change_ring(ZZ)
2653
+ True
2654
+
2655
+ A matrix without size control may have very large entry sizes. ::
2656
+
2657
+ sage: D = random_matrix(ZZ, 7, 8, algorithm='echelonizable', rank=6); D # random
2658
+ [ 1 2 8 -35 -178 -239 -284 778]
2659
+ [ 4 9 37 -163 -827 -1111 -1324 3624]
2660
+ [ 5 6 21 -88 -454 -607 -708 1951]
2661
+ [ -4 -5 -22 97 491 656 779 -2140]
2662
+ [ 4 4 13 -55 -283 -377 -436 1206]
2663
+ [ 4 11 43 -194 -982 -1319 -1576 4310]
2664
+ [ -1 -2 -13 59 294 394 481 -1312]
2665
+
2666
+ Matrices can be generated over any exact ring. ::
2667
+
2668
+ sage: # needs sage.rings.finite_rings
2669
+ sage: F.<a> = GF(2^3)
2670
+ sage: B = random_matrix(F, 4, 5, algorithm='echelonizable', rank=4,
2671
+ ....: upper_bound=None)
2672
+ sage: B.rank()
2673
+ 4
2674
+ sage: B.base_ring() is F
2675
+ True
2676
+
2677
+ Square matrices over ZZ or QQ with full rank are always unimodular. ::
2678
+
2679
+ sage: E = random_matrix(QQ, 7, 7, algorithm='echelonizable', rank=7)
2680
+ sage: det(E)
2681
+ 1
2682
+ sage: E = random_matrix(ZZ, 7, 7, algorithm='echelonizable', rank=7)
2683
+ sage: det(E)
2684
+ 1
2685
+
2686
+ TESTS:
2687
+
2688
+ Matrices must have a rank zero or greater, and less than
2689
+ both the number of rows and the number of columns. ::
2690
+
2691
+ sage: random_matrix(QQ, 3, 4, algorithm='echelonizable', rank=-1)
2692
+ Traceback (most recent call last):
2693
+ ...
2694
+ ValueError: matrices must have rank zero or greater.
2695
+ sage: random_matrix(QQ, 3, 8, algorithm='echelonizable', rank=4)
2696
+ Traceback (most recent call last):
2697
+ ...
2698
+ ValueError: matrices cannot have rank greater than min(ncols,nrows).
2699
+ sage: random_matrix(QQ, 8, 3, algorithm='echelonizable', rank=4)
2700
+ Traceback (most recent call last):
2701
+ ...
2702
+ ValueError: matrices cannot have rank greater than min(ncols,nrows).
2703
+
2704
+ The base ring must be exact. ::
2705
+
2706
+ sage: random_matrix(RR, 3, 3, algorithm='echelonizable', rank=2)
2707
+ Traceback (most recent call last):
2708
+ ...
2709
+ TypeError: the base ring must be exact
2710
+
2711
+ Works for rank==1, too. ::
2712
+
2713
+ sage: random_matrix(QQ, 3, 3, algorithm='echelonizable', rank=1).ncols()
2714
+ 3
2715
+
2716
+
2717
+ AUTHOR:
2718
+
2719
+ Billy Wonderly (2010-07)
2720
+ """
2721
+ from sage.misc.prandom import randint
2722
+
2723
+ ring = parent.base_ring()
2724
+ rows = parent.nrows()
2725
+ if rank < 0:
2726
+ raise ValueError("matrices must have rank zero or greater.")
2727
+ if rank > min(rows,parent.ncols()):
2728
+ raise ValueError("matrices cannot have rank greater than min(ncols,nrows).")
2729
+ matrix = random_rref_matrix(parent, rank)
2730
+
2731
+ # Entries of matrices over the ZZ or QQ can get large, entry size is regulated by finding the largest
2732
+ # entry of the resultant matrix after addition of scalar multiple of a row.
2733
+ if ring is QQ or ring is ZZ:
2734
+ # If upper_bound is not set, don't control entry size.
2735
+ if upper_bound is None:
2736
+ # If size control is not desired, the routine will run slightly faster, particularly with large matrices.
2737
+ for pivots in range(rank-1, -1, -1):
2738
+ row_index = 0
2739
+ while row_index < rows:
2740
+ if pivots == row_index:
2741
+ row_index += 1
2742
+ if pivots != row_index and row_index != rows:
2743
+ matrix.add_multiple_of_row(row_index,
2744
+ matrix.pivot_rows()[pivots],
2745
+ randint(-5, 5))
2746
+ row_index += 1
2747
+ if rows > 1:
2748
+ matrix.add_multiple_of_row(0, randint(1,rows-1), randint(-3,3))
2749
+ else:
2750
+ if rank == 1: # would be better just to have a special generator...
2751
+ tries = 0
2752
+ while max(abs(c) for c in matrix.list()) >= upper_bound:
2753
+ matrix = random_rref_matrix(parent, rank)
2754
+ tries += 1
2755
+ if tries > max_tries: # to prevent endless attempts
2756
+ raise ValueError("tried "+str(max_tries)+" times to get a rank 1 random matrix. Try bigger upper_bound?")
2757
+ matrix_copy = matrix
2758
+
2759
+ for pivots in range(len(matrix.pivots()) - 1, -1, -1):
2760
+ # keep track of the pivot column positions from the pivot column with the largest index to
2761
+ # the one with the smallest.
2762
+ row_index = 0
2763
+ tries = 0
2764
+ while row_index < rows:
2765
+ # To each row in a pivot column add a scalar multiple of the pivot row.
2766
+ # for full rank, square matrices, using only this row operation preserves the determinant of 1.
2767
+ if pivots != row_index:
2768
+ # To ensure a leading one is not removed by the addition of the pivot row by its
2769
+ # additive inverse.
2770
+ matrix_copy = matrix.with_added_multiple_of_row(row_index,matrix.pivot_rows()[pivots],randint(-5,5))
2771
+ tries += 1
2772
+ # Range for scalar multiples determined experimentally.
2773
+ if max(map(abs, matrix_copy.list())) < upper_bound:
2774
+ # Continue if the largest entry after a row operation is within the bound.
2775
+ matrix = matrix_copy
2776
+ row_index += 1
2777
+ tries = 0
2778
+ if tries > max_tries: # to prevent endless unsuccessful row adding
2779
+ raise ValueError("tried "+str(max_tries)+" times to get row number "+str(row_index)+". Try bigger upper_bound?")
2780
+ # The leading one in row one has not been altered, so add a scalar multiple of a random row
2781
+ # to row one.
2782
+ row1 = 0
2783
+ if rows > 1:
2784
+ while row1 < 1:
2785
+ matrix_copy = matrix.with_added_multiple_of_row(0,randint(1,rows-1),randint(-3,3))
2786
+ if max(map(abs,matrix_copy.list())) < upper_bound:
2787
+ matrix = matrix_copy
2788
+ row1 += 1
2789
+ # If the matrix generated over a different ring, random elements from the designated ring are used as and
2790
+ # the routine is run similarly to the size unchecked version for rationals and integers.
2791
+ else:
2792
+ for pivots in range(rank-1,-1,-1):
2793
+ row_index = 0
2794
+ while row_index < rows:
2795
+ if pivots == row_index:
2796
+ row_index += 1
2797
+ if pivots != row_index and row_index != rows:
2798
+ matrix.add_multiple_of_row(row_index,matrix.pivot_rows()[pivots],ring.random_element())
2799
+ row_index += 1
2800
+ if rows > 1:
2801
+ matrix.add_multiple_of_row(0,randint(1,rows-1),ring.random_element())
2802
+ return matrix
2803
+
2804
+
2805
+ @matrix_method
2806
+ def random_subspaces_matrix(parent, rank=None):
2807
+ r"""
2808
+ Create a matrix of the designated size and rank whose right and
2809
+ left null spaces, column space, and row space have desirable
2810
+ properties that simplify the subspaces.
2811
+
2812
+ INPUT:
2813
+
2814
+ - ``parent`` -- a matrix space specifying the base ring, dimensions, and
2815
+ representation (dense/sparse) for the result. The base ring must be exact.
2816
+
2817
+ - ``rank`` -- the desired rank of the return matrix (default: ``None``)
2818
+
2819
+ OUTPUT:
2820
+
2821
+ A matrix whose natural basis vectors for its four subspaces, when
2822
+ computed, have reasonably sized, integral valued, entries.
2823
+
2824
+ .. NOTE::
2825
+
2826
+ It is easiest to use this function via a call to the
2827
+ :func:`~sage.matrix.constructor.random_matrix`
2828
+ function with the ``algorithm='subspaces'`` keyword. We provide
2829
+ one example accessing this function directly, while the remainder will
2830
+ use this more general function.
2831
+
2832
+ EXAMPLES:
2833
+
2834
+ A 6x8 matrix with designated rank of 3. The four subspaces are
2835
+ determined using one simple routine in which we augment the
2836
+ original matrix with the equal row dimension identity matrix. The
2837
+ resulting matrix is then put in reduced row-echelon form and the
2838
+ subspaces can then be determined by analyzing subdivisions of this
2839
+ matrix. See the four subspaces routine in [Bee]_ for more. ::
2840
+
2841
+ sage: from sage.matrix.constructor import random_subspaces_matrix
2842
+ sage: matrix_space = sage.matrix.matrix_space.MatrixSpace(QQ, 6, 8)
2843
+ sage: B = random_subspaces_matrix(matrix_space, rank=3)
2844
+ sage: B.rank()
2845
+ 3
2846
+ sage: B.nullity()
2847
+ 3
2848
+ sage: (B.nrows(), B.ncols())
2849
+ (6, 8)
2850
+ sage: all(x in ZZ for x in B.list())
2851
+ True
2852
+ sage: B_expanded = B.augment(identity_matrix(6)).rref()
2853
+ sage: all(x in ZZ for x in B_expanded.list())
2854
+ True
2855
+
2856
+ Check that we fixed :issue:`10543` (echelon forms should be immutable)::
2857
+
2858
+ sage: B_expanded.is_immutable()
2859
+ True
2860
+
2861
+ We want to modify B_expanded, so replace it with a copy::
2862
+
2863
+ sage: B_expanded = copy(B_expanded)
2864
+ sage: B_expanded.subdivide(B.nrows()-B.nullity(), B.ncols())
2865
+ sage: C = B_expanded.subdivision(0, 0)
2866
+ sage: L = B_expanded.subdivision(1, 1)
2867
+ sage: B.right_kernel() == C.right_kernel()
2868
+ True
2869
+ sage: B.row_space() == C.row_space()
2870
+ True
2871
+ sage: B.column_space() == L.right_kernel()
2872
+ True
2873
+ sage: B.left_kernel() == L.row_space()
2874
+ True
2875
+
2876
+ A matrix to show that the null space of the L matrix is the column space of the starting matrix. ::
2877
+
2878
+ sage: A = random_matrix(QQ, 5, 7, algorithm='subspaces', rank=None)
2879
+ sage: (A.nrows(), A.ncols())
2880
+ (5, 7)
2881
+ sage: all(x in ZZ for x in A.list())
2882
+ True
2883
+ sage: A_expanded = A.augment(identity_matrix(5)).rref()
2884
+ sage: all(x in ZZ for x in A_expanded.list())
2885
+ True
2886
+ sage: C = A_expanded.submatrix(0, 0, A.nrows() - A.nullity(), A.ncols())
2887
+ sage: L = A_expanded.submatrix(A.nrows() - A.nullity(), A.ncols())
2888
+ sage: A.right_kernel() == C.right_kernel()
2889
+ True
2890
+ sage: A.row_space() == C.row_space()
2891
+ True
2892
+ sage: A.column_space() == L.right_kernel()
2893
+ True
2894
+ sage: A.left_kernel() == L.row_space()
2895
+ True
2896
+
2897
+ TESTS:
2898
+
2899
+ The designated rank of the L matrix cannot be greater than the
2900
+ number of desired rows, nor can the rank be negative. ::
2901
+
2902
+ sage: random_matrix(QQ, 19, 20, algorithm='subspaces', rank=21)
2903
+ Traceback (most recent call last):
2904
+ ...
2905
+ ValueError: rank cannot exceed the number of rows or columns.
2906
+ sage: random_matrix(QQ, 19, 20, algorithm='subspaces', rank=-1)
2907
+ Traceback (most recent call last):
2908
+ ...
2909
+ ValueError: matrices must have rank zero or greater.
2910
+
2911
+ AUTHOR:
2912
+
2913
+ Billy Wonderly (2010-07)
2914
+ """
2915
+
2916
+ import sage.probability.probability_distribution as pd
2917
+
2918
+ ring = parent.base_ring()
2919
+ rows = parent.nrows()
2920
+ columns = parent.ncols()
2921
+
2922
+ # If rank is not designated, generate using probability distribution
2923
+ # skewing to smaller numbers, always at least 1.
2924
+ if rank is None:
2925
+ left_nullity_generator = pd.RealDistribution("beta", [1.4, 5.5])
2926
+ nullity = int(left_nullity_generator.get_random_element()*(rows-1) + 1)
2927
+ rank = rows - nullity
2928
+ if rank < 0:
2929
+ raise ValueError("matrices must have rank zero or greater.")
2930
+ if rank > rows or rank > columns:
2931
+ raise ValueError("rank cannot exceed the number of rows or columns.")
2932
+ nullity = rows - rank
2933
+ B = random_matrix(ring, rows, columns, algorithm='echelon_form',
2934
+ num_pivots=rank)
2935
+
2936
+ # Create a nonsingular matrix whose columns will be used to stack a matrix
2937
+ # over the L matrix, forming a nonsingular matrix.
2938
+ K_nonzero_columns = random_matrix(ring, rank, rank,
2939
+ algorithm='echelonizable', rank=rank)
2940
+ K = matrix(QQ, rank, rows)
2941
+ L = random_matrix(ring, nullity, rows, algorithm='echelon_form',
2942
+ num_pivots=nullity)
2943
+ for column in range(len(L.nonpivots())):
2944
+ for entry in range(rank):
2945
+ K[entry, L.nonpivots()[column]] = K_nonzero_columns[entry, column]
2946
+ J = K.stack(L)
2947
+
2948
+ # By multiplying the B matrix by J.inverse() we hide the B matrix of the
2949
+ # solution using row operations required to change the solution K matrix to
2950
+ # the identity matrix.
2951
+ return J.inverse() * B
2952
+
2953
+
2954
+ @matrix_method
2955
+ def random_unimodular_matrix(parent, upper_bound=None, max_tries=100):
2956
+ r"""
2957
+ Generate a random unimodular (determinant 1) matrix of a desired size over a desired ring.
2958
+
2959
+ INPUT:
2960
+
2961
+ - ``parent`` -- a matrix space specifying the base ring, dimensions
2962
+ and representation (dense/sparse) for the result. The base ring
2963
+ must be exact.
2964
+
2965
+ - ``upper_bound`` -- for large matrices over QQ or ZZ,
2966
+ ``upper_bound`` is the largest value matrix entries can achieve. But
2967
+ see the warning below.
2968
+
2969
+ - ``max_tries`` -- if designated, number of tries used to generate each new random row;
2970
+ only matters when upper_bound!=None. Used to prevent endless looping. (default: 100)
2971
+
2972
+ A matrix not in reduced row-echelon form with the desired dimensions and properties.
2973
+
2974
+ OUTPUT: an invertible matrix with the desired properties and determinant 1
2975
+
2976
+ .. warning::
2977
+
2978
+ When ``upper_bound`` is set, it is possible for this constructor to
2979
+ fail with a :exc:`ValueError`. This may happen when the ``upper_bound``,
2980
+ ``rank`` and/or matrix dimensions are all so small that it becomes
2981
+ infeasible or unlikely to create the requested matrix. If you *must*
2982
+ have this routine return successfully, do not set ``upper_bound``.
2983
+
2984
+ .. NOTE::
2985
+
2986
+ It is easiest to use this function via a call to the
2987
+ :func:`~sage.matrix.constructor.random_matrix`
2988
+ function with the ``algorithm='unimodular'`` keyword. We provide
2989
+ one example accessing this function directly, while the remainder will
2990
+ use this more general function.
2991
+
2992
+ EXAMPLES:
2993
+
2994
+ A matrix size 5 over QQ. ::
2995
+
2996
+ sage: from sage.matrix.constructor import random_unimodular_matrix
2997
+ sage: matrix_space = sage.matrix.matrix_space.MatrixSpace(QQ, 5)
2998
+ sage: A = random_unimodular_matrix(matrix_space)
2999
+ sage: det(A)
3000
+ 1
3001
+
3002
+ A matrix size 6 with entries no larger than 50. ::
3003
+
3004
+ sage: B = random_matrix(ZZ, 7, algorithm='unimodular', upper_bound=50)
3005
+ sage: det(B)
3006
+ 1
3007
+ sage: all(abs(b) < 50 for b in B.list())
3008
+ True
3009
+
3010
+ A matrix over the number Field in `y` with defining polynomial `y^2-2y-2`. ::
3011
+
3012
+ sage: # needs sage.rings.number_field
3013
+ sage: y = polygen(ZZ, 'y')
3014
+ sage: K = NumberField(y^2 - 2*y - 2, 'y')
3015
+ sage: C = random_matrix(K, 3, algorithm='unimodular')
3016
+ sage: C # random
3017
+ [ -1/7*y + 47/35 3/5*y - 127/70 -2917/70*y + 4419/70]
3018
+ [ 1 1/2*y - 1/2 -104/3*y + 211/6]
3019
+ [ 1/3*y - 1/3 y - 1 -35/6*y - 149/6]
3020
+ sage: det(C)
3021
+ 1
3022
+ sage: C.base_ring() is K
3023
+ True
3024
+
3025
+ TESTS:
3026
+
3027
+ Unimodular matrices are square. ::
3028
+
3029
+ sage: random_matrix(QQ, 5, 6, algorithm='unimodular')
3030
+ Traceback (most recent call last):
3031
+ ...
3032
+ TypeError: a unimodular matrix must be square.
3033
+
3034
+ Only matrices over ZZ and QQ can have size control. ::
3035
+
3036
+ sage: F.<a> = GF(5^7) # needs sage.rings.finite_rings
3037
+ sage: random_matrix(F, 5, algorithm='unimodular', upper_bound=20) # needs sage.rings.finite_rings
3038
+ Traceback (most recent call last):
3039
+ ...
3040
+ TypeError: only matrices over ZZ or QQ can have size control.
3041
+
3042
+ AUTHOR:
3043
+
3044
+ Billy Wonderly (2010-07)
3045
+ """
3046
+
3047
+ ring = parent.base_ring()
3048
+ size = parent.nrows()
3049
+ if parent.nrows() != parent.ncols():
3050
+ raise TypeError("a unimodular matrix must be square.")
3051
+ if upper_bound is not None and (ring != ZZ and ring != QQ):
3052
+ raise TypeError("only matrices over ZZ or QQ can have size control.")
3053
+ if upper_bound is None:
3054
+ # random_echelonizable_matrix() always returns a determinant one matrix if given full rank.
3055
+ return random_matrix(ring, size, algorithm='echelonizable', rank=size)
3056
+ elif upper_bound is not None and (ring == ZZ or ring == QQ):
3057
+ return random_matrix(ring, size,algorithm='echelonizable',rank=size, upper_bound=upper_bound, max_tries=max_tries)
3058
+
3059
+
3060
+ @matrix_method
3061
+ def random_diagonalizable_matrix(parent, eigenvalues=None, dimensions=None):
3062
+ """
3063
+ Create a random matrix that diagonalizes nicely.
3064
+
3065
+ To be used as a teaching tool. The eigenvalues will be elements of the
3066
+ base ring. If the base ring used is ``QQ`` then the returned matrix will
3067
+ have integer eigenvalues.
3068
+
3069
+ INPUT:
3070
+
3071
+ If eigenvalues and dimensions are not specified in a list,
3072
+ they will be assigned randomly.
3073
+
3074
+ - ``parent`` -- the desired parent of the square matrix (a matrix space)
3075
+
3076
+ - ``eigenvalues`` -- the list of desired eigenvalues (default=None)
3077
+
3078
+ - ``dimensions`` -- the list of dimensions corresponding to each
3079
+ eigenspace (default=None)
3080
+
3081
+ OUTPUT:
3082
+
3083
+ A square, diagonalizable, matrix. Elements of the matrix are elements
3084
+ of the base ring. If the ring used is ``QQ`` then we have integer entries,
3085
+ and the eigenspaces of this matrix, if computed by hand, gives basis
3086
+ vectors with only integer entries.
3087
+
3088
+ .. NOTE::
3089
+
3090
+ It is easiest to use this function via a call to the
3091
+ :func:`~sage.matrix.constructor.random_matrix`
3092
+ function with the ``algorithm='diagonalizable'`` keyword. We provide
3093
+ one example accessing this function directly, while the remainder will
3094
+ use this more general function.
3095
+
3096
+ EXAMPLES:
3097
+
3098
+ A diagonalizable matrix, size 5. ::
3099
+
3100
+ sage: from sage.matrix.constructor import random_diagonalizable_matrix
3101
+ sage: matrix_space = sage.matrix.matrix_space.MatrixSpace(QQ, 5)
3102
+ sage: A = random_diagonalizable_matrix(matrix_space)
3103
+
3104
+ sage: # needs sage.rings.number_field
3105
+ sage: eigenvalues = A.eigenvalues()
3106
+ sage: S = A.right_eigenmatrix()[1]
3107
+ sage: eigenvalues2 = (S.inverse()*A*S).diagonal()
3108
+ sage: sorted(eigenvalues) == sorted(eigenvalues2)
3109
+ True
3110
+
3111
+ A diagonalizable matrix with eigenvalues and dimensions designated,
3112
+ with a check that if eigenvectors were calculated by hand
3113
+ entries would all be integers. ::
3114
+
3115
+ sage: eigenvalues = [ZZ.random_element() for _ in range(3)]
3116
+ sage: B = random_matrix(QQ, 6, algorithm='diagonalizable',
3117
+ ....: eigenvalues=eigenvalues, dimensions=[2,3,1])
3118
+ sage: all(x in ZZ for x in (B-(-12*identity_matrix(6))).rref().list())
3119
+ True
3120
+ sage: all(x in ZZ for x in (B-(4*identity_matrix(6))).rref().list())
3121
+ True
3122
+ sage: all(x in ZZ for x in (B-(6*identity_matrix(6))).rref().list())
3123
+ True
3124
+
3125
+ sage: # needs sage.rings.number_field
3126
+ sage: S = B.right_eigenmatrix()[1]
3127
+ sage: eigenvalues2 = (S.inverse()*B*S).diagonal()
3128
+ sage: all(e in eigenvalues for e in eigenvalues2)
3129
+ True
3130
+
3131
+ Matrices over finite fields are also supported::
3132
+
3133
+ sage: K = GF(3)
3134
+ sage: M = random_matrix(K, 3, 3, algorithm="diagonalizable")
3135
+ sage: M.parent()
3136
+ Full MatrixSpace of 3 by 3 dense matrices over Finite Field of size 3
3137
+ sage: M.is_diagonalizable() # needs sage.libs.pari
3138
+ True
3139
+ sage: M # random
3140
+ [0 0 1]
3141
+ [2 1 1]
3142
+ [1 0 0]
3143
+
3144
+ TESTS:
3145
+
3146
+ Eigenvalues must all be elements of the ring. ::
3147
+
3148
+ sage: random_matrix(QQ, 3, algorithm='diagonalizable', # needs sage.symbolic
3149
+ ....: eigenvalues=[2+I, 2-I, 2], dimensions=[1,1,1])
3150
+ Traceback (most recent call last):
3151
+ ...
3152
+ TypeError: eigenvalues must be elements of the corresponding ring.
3153
+
3154
+ Diagonal matrices must be square. ::
3155
+
3156
+ sage: random_matrix(QQ, 5, 7, algorithm='diagonalizable', eigenvalues=[-5,2,-3], dimensions=[1,1,3])
3157
+ Traceback (most recent call last):
3158
+ ...
3159
+ TypeError: a diagonalizable matrix must be square.
3160
+
3161
+ A list of eigenvalues must be accompanied with a list of dimensions. ::
3162
+
3163
+ sage: random_matrix(QQ,10,algorithm='diagonalizable',eigenvalues=[4,8])
3164
+ Traceback (most recent call last):
3165
+ ...
3166
+ ValueError: the list of eigenvalues must have a list of dimensions corresponding to each eigenvalue.
3167
+
3168
+ A list of dimensions must be accompanied with a list of eigenvalues. ::
3169
+
3170
+ sage: random_matrix(QQ, 10,algorithm='diagonalizable',dimensions=[2,2,4,2])
3171
+ Traceback (most recent call last):
3172
+ ...
3173
+ ValueError: the list of dimensions must have a list of corresponding eigenvalues.
3174
+
3175
+ The sum of the eigenvalue dimensions must equal the size of the matrix. ::
3176
+
3177
+ sage: random_matrix(QQ,12,algorithm='diagonalizable',eigenvalues=[4,2,6,-1],dimensions=[2,3,5,1])
3178
+ Traceback (most recent call last):
3179
+ ...
3180
+ ValueError: the size of the matrix must equal the sum of the dimensions.
3181
+
3182
+ Each eigenspace dimension must be at least 1. ::
3183
+
3184
+ sage: random_matrix(QQ,9,algorithm='diagonalizable',eigenvalues=[-15,22,8,-4,90,12],dimensions=[4,2,2,4,-3,0])
3185
+ Traceback (most recent call last):
3186
+ ...
3187
+ ValueError: eigenspaces must have a dimension of at least 1.
3188
+
3189
+ Each eigenvalue must have a corresponding eigenspace dimension. ::
3190
+
3191
+ sage: random_matrix(QQ,12,algorithm='diagonalizable',eigenvalues=[4,2,6,-1],dimensions=[4,3,5])
3192
+ Traceback (most recent call last):
3193
+ ...
3194
+ ValueError: each eigenvalue must have a corresponding dimension and each dimension a corresponding eigenvalue.
3195
+
3196
+ Each dimension must have an eigenvalue paired to it. ::
3197
+
3198
+ sage: random_matrix(QQ,12,algorithm='diagonalizable',eigenvalues=[4,2,6],dimensions=[2,3,5,2])
3199
+ Traceback (most recent call last):
3200
+ ...
3201
+ ValueError: each eigenvalue must have a corresponding dimension and each dimension a corresponding eigenvalue.
3202
+
3203
+ .. TODO::
3204
+
3205
+ Modify the routine to allow for complex eigenvalues.
3206
+
3207
+ AUTHOR:
3208
+
3209
+ Billy Wonderly (2010-07)
3210
+ """
3211
+
3212
+ from sage.misc.prandom import randint
3213
+
3214
+ size = parent.nrows()
3215
+ ring = parent.base_ring()
3216
+ if parent.nrows() != parent.ncols():
3217
+ raise TypeError("a diagonalizable matrix must be square.")
3218
+ if eigenvalues is not None and dimensions is None:
3219
+ raise ValueError("the list of eigenvalues must have a list of dimensions corresponding to each eigenvalue.")
3220
+ if eigenvalues is None and dimensions is not None:
3221
+ raise ValueError("the list of dimensions must have a list of corresponding eigenvalues.")
3222
+ if eigenvalues is None and dimensions is None:
3223
+ values = []
3224
+ # create a list with "size" number of entries
3225
+ for eigen_index in range(size):
3226
+ eigenvalue = ring(randint(-10, 10))
3227
+ values.append(eigenvalue)
3228
+ values.sort()
3229
+ dimensions = []
3230
+ eigenvalues = []
3231
+ # create a list with no duplicate values to be the eigenvalues
3232
+ for eigenvalue in range(size):
3233
+ if values[eigenvalue] not in eigenvalues:
3234
+ eigenvalues.append(values[eigenvalue])
3235
+ for dimension in range(len(eigenvalues)):
3236
+ # dimension is equal to how many times an eigenvalue was generated in the 'values' list
3237
+ dimensions.append(values.count(eigenvalues[dimension]))
3238
+ size_check = 0
3239
+ for check in range(len(dimensions)):
3240
+ size_check = size_check + dimensions[check]
3241
+ if not all(x in ring for x in eigenvalues):
3242
+ raise TypeError("eigenvalues must be elements of the corresponding ring.")
3243
+ if size != size_check:
3244
+ raise ValueError("the size of the matrix must equal the sum of the dimensions.")
3245
+ if min(dimensions) < 1:
3246
+ raise ValueError("eigenspaces must have a dimension of at least 1.")
3247
+ if len(eigenvalues) != len(dimensions):
3248
+ raise ValueError("each eigenvalue must have a corresponding dimension and each dimension a corresponding eigenvalue.")
3249
+ # sort the dimensions in order of increasing size, and sort the eigenvalues list in an identical fashion, to maintain corresponding values.
3250
+ dimensions_sort = sorted(zip(dimensions, eigenvalues))
3251
+ dimensions = [x[0] for x in dimensions_sort]
3252
+ eigenvalues = [x[1] for x in dimensions_sort]
3253
+ # Create the matrix of eigenvalues on the diagonal. Use a lower limit and upper limit determined by the eigenvalue dimensions.
3254
+ diagonal_matrix = matrix(ring, size)
3255
+ up_bound = 0
3256
+ low_bound = 0
3257
+ for row_index in range(len(dimensions)):
3258
+ up_bound = up_bound + dimensions[row_index]
3259
+ for entry in range(low_bound,up_bound):
3260
+ diagonal_matrix[entry, entry] = eigenvalues[row_index]
3261
+ low_bound = low_bound+dimensions[row_index]
3262
+ # Create a matrix to hold each of the eigenvectors as its columns, begin with an identity matrix so that after row and column
3263
+ # operations the resulting matrix will be unimodular.
3264
+ eigenvector_matrix = matrix.identity(ring, size)
3265
+ upper_limit = 0
3266
+ lower_limit = 0
3267
+ # run the routine over the necessary number of columns corresponding eigenvalue dimension.
3268
+ for dimension_index in range(len(dimensions)-1):
3269
+ upper_limit = upper_limit+dimensions[dimension_index]
3270
+ lowest_index_row_with_one = size-dimensions[dimension_index]
3271
+ # assign a one to the row that is the eigenvalue dimension rows up from the bottom row then assign ones diagonally down to the right.
3272
+ for eigen_ones in range(lower_limit,upper_limit):
3273
+ eigenvector_matrix[lowest_index_row_with_one,eigen_ones] = 1
3274
+ lowest_index_row_with_one += 1
3275
+ lower_limit = lower_limit+dimensions[dimension_index]
3276
+ # Create a list to give the eigenvalue dimension corresponding to each column.
3277
+ dimension_check = []
3278
+ for i in range(len(dimensions)):
3279
+ for k in range(dimensions[i]):
3280
+ dimension_check.append(dimensions[i])
3281
+ # run routine over the rows that are in the range of the protected ones. Use addition of column multiples to fill entries.
3282
+ for dimension_multiplicity in range(max(dimensions),min(dimensions),-1):
3283
+ highest_one_row = size-dimension_multiplicity
3284
+ highest_one_column = 0
3285
+ # find the column with the protected one in the lowest indexed row.
3286
+ while eigenvector_matrix[highest_one_row,highest_one_column] == 0:
3287
+ highest_one_column += 1
3288
+ # dimension_check determines if column has a low enough eigenvalue dimension to take a column multiple.
3289
+ for bottom_entry_filler in range(len(dimension_check)):
3290
+ if dimension_check[bottom_entry_filler] < dimension_multiplicity and eigenvector_matrix[highest_one_row,bottom_entry_filler] == 0:
3291
+ # randint range determined experimentally to keep entries manageable.
3292
+ eigenvector_matrix.add_multiple_of_column(bottom_entry_filler,highest_one_column,randint(-4,4))
3293
+ # Fill remaining rows using scalar row addition.
3294
+ for row in range(size-max(dimensions),size):
3295
+ for upper_row in range(size-max(dimensions)):
3296
+ # range of multiplier determined experimentally so that entries stay manageable for small matrices
3297
+ eigenvector_matrix.add_multiple_of_row(upper_row,row,randint(-4,4))
3298
+ return eigenvector_matrix*diagonal_matrix*(eigenvector_matrix.inverse())
3299
+
3300
+
3301
+ @matrix_method
3302
+ def vector_on_axis_rotation_matrix(v, i, ring=None):
3303
+ r"""
3304
+ Return a rotation matrix `M` such that `det(M)=1` sending the vector
3305
+ `v` on the `i`-th axis so that all other coordinates of `Mv` are zero.
3306
+
3307
+ .. NOTE::
3308
+
3309
+ Such a matrix is not uniquely determined. This function returns one
3310
+ such matrix.
3311
+
3312
+ INPUT:
3313
+
3314
+ - ``v`` -- vector
3315
+ - ``i`` -- integer
3316
+ - ``ring`` -- ring (default: ``None``) of the resulting matrix
3317
+
3318
+ OUTPUT: a matrix
3319
+
3320
+ EXAMPLES::
3321
+
3322
+ sage: from sage.matrix.constructor import vector_on_axis_rotation_matrix
3323
+ sage: v = vector((1,2,3))
3324
+ sage: vector_on_axis_rotation_matrix(v, 2) * v # needs sage.symbolic
3325
+ (0, 0, sqrt(14))
3326
+ sage: vector_on_axis_rotation_matrix(v, 1) * v # needs sage.symbolic
3327
+ (0, sqrt(14), 0)
3328
+ sage: vector_on_axis_rotation_matrix(v, 0) * v # needs sage.symbolic
3329
+ (sqrt(14), 0, 0)
3330
+
3331
+ ::
3332
+
3333
+ sage: # needs sage.symbolic
3334
+ sage: x,y = var('x,y')
3335
+ sage: v = vector((x,y))
3336
+ sage: vector_on_axis_rotation_matrix(v, 1)
3337
+ [ y/sqrt(x^2 + y^2) -x/sqrt(x^2 + y^2)]
3338
+ [ x/sqrt(x^2 + y^2) y/sqrt(x^2 + y^2)]
3339
+ sage: vector_on_axis_rotation_matrix(v, 0)
3340
+ [ x/sqrt(x^2 + y^2) y/sqrt(x^2 + y^2)]
3341
+ [-y/sqrt(x^2 + y^2) x/sqrt(x^2 + y^2)]
3342
+ sage: vector_on_axis_rotation_matrix(v, 0) * v
3343
+ (x^2/sqrt(x^2 + y^2) + y^2/sqrt(x^2 + y^2), 0)
3344
+ sage: vector_on_axis_rotation_matrix(v, 1) * v
3345
+ (0, x^2/sqrt(x^2 + y^2) + y^2/sqrt(x^2 + y^2))
3346
+
3347
+ ::
3348
+
3349
+ sage: v = vector((1,2,3,4))
3350
+ sage: vector_on_axis_rotation_matrix(v, 0) * v # needs sage.symbolic
3351
+ (sqrt(30), 0, 0, 0)
3352
+ sage: vector_on_axis_rotation_matrix(v, 0, ring=RealField(10))
3353
+ [ 0.18 0.37 0.55 0.73]
3354
+ [-0.98 0.068 0.10 0.14]
3355
+ [ 0.00 -0.93 0.22 0.30]
3356
+ [ 0.00 0.00 -0.80 0.60]
3357
+ sage: vector_on_axis_rotation_matrix(v, 0, ring=RealField(10)) * v
3358
+ (5.5, 0.00..., 0.00..., 0.00...)
3359
+
3360
+ AUTHORS:
3361
+
3362
+ Sébastien Labbé (April 2010)
3363
+ """
3364
+ dim = len(v)
3365
+ v = vector(v)
3366
+ m = identity_matrix(dim, sparse=True)
3367
+ L = list(range(i - 1, -1, -1)) + list(range(dim - 1, i, -1))
3368
+ for i in L:
3369
+ rot = ith_to_zero_rotation_matrix(v, i, ring=ring)
3370
+ v = rot * v
3371
+ m = rot * m
3372
+ return m
3373
+
3374
+
3375
+ @matrix_method
3376
+ def ith_to_zero_rotation_matrix(v, i, ring=None):
3377
+ r"""
3378
+ Return a rotation matrix that sends the `i`-th coordinates of the
3379
+ vector v to zero by doing a rotation with the `(i-1)`-th coordinate.
3380
+
3381
+ INPUT:
3382
+
3383
+ - ``v`` -- vector
3384
+ - ``i`` -- integer
3385
+ - ``ring`` -- ring (default: ``None``) of the resulting matrix
3386
+
3387
+ OUTPUT: a matrix
3388
+
3389
+ EXAMPLES::
3390
+
3391
+ sage: from sage.matrix.constructor import ith_to_zero_rotation_matrix
3392
+ sage: v = vector((1,2,3))
3393
+ sage: ith_to_zero_rotation_matrix(v, 2) # needs sage.symbolic
3394
+ [ 1 0 0]
3395
+ [ 0 2/13*sqrt(13) 3/13*sqrt(13)]
3396
+ [ 0 -3/13*sqrt(13) 2/13*sqrt(13)]
3397
+ sage: ith_to_zero_rotation_matrix(v, 2) * v # needs sage.symbolic
3398
+ (1, sqrt(13), 0)
3399
+
3400
+ ::
3401
+
3402
+ sage: ith_to_zero_rotation_matrix(v, 0) # needs sage.symbolic
3403
+ [ 3/10*sqrt(10) 0 -1/10*sqrt(10)]
3404
+ [ 0 1 0]
3405
+ [ 1/10*sqrt(10) 0 3/10*sqrt(10)]
3406
+ sage: ith_to_zero_rotation_matrix(v, 1) # needs sage.symbolic
3407
+ [ 1/5*sqrt(5) 2/5*sqrt(5) 0]
3408
+ [-2/5*sqrt(5) 1/5*sqrt(5) 0]
3409
+ [ 0 0 1]
3410
+ sage: ith_to_zero_rotation_matrix(v, 2) # needs sage.symbolic
3411
+ [ 1 0 0]
3412
+ [ 0 2/13*sqrt(13) 3/13*sqrt(13)]
3413
+ [ 0 -3/13*sqrt(13) 2/13*sqrt(13)]
3414
+
3415
+ ::
3416
+
3417
+ sage: ith_to_zero_rotation_matrix(v, 0) * v # needs sage.symbolic
3418
+ (0, 2, sqrt(10))
3419
+ sage: ith_to_zero_rotation_matrix(v, 1) * v # needs sage.symbolic
3420
+ (sqrt(5), 0, 3)
3421
+ sage: ith_to_zero_rotation_matrix(v, 2) * v # needs sage.symbolic
3422
+ (1, sqrt(13), 0)
3423
+
3424
+ Other ring::
3425
+
3426
+ sage: ith_to_zero_rotation_matrix(v, 2, ring=RR)
3427
+ [ 1.00000000000000 0.000000000000000 0.000000000000000]
3428
+ [ 0.000000000000000 0.554700196225229 0.832050294337844]
3429
+ [ 0.000000000000000 -0.832050294337844 0.554700196225229]
3430
+ sage: ith_to_zero_rotation_matrix(v, 2, ring=RDF)
3431
+ [ 1.0 0.0 0.0]
3432
+ [ 0.0 0.5547001962252291 0.8320502943378437]
3433
+ [ 0.0 -0.8320502943378437 0.5547001962252291]
3434
+
3435
+ On the symbolic ring::
3436
+
3437
+ sage: # needs sage.symbolic
3438
+ sage: x,y,z = var('x,y,z')
3439
+ sage: v = vector((x,y,z))
3440
+ sage: ith_to_zero_rotation_matrix(v, 2)
3441
+ [ 1 0 0]
3442
+ [ 0 y/sqrt(y^2 + z^2) z/sqrt(y^2 + z^2)]
3443
+ [ 0 -z/sqrt(y^2 + z^2) y/sqrt(y^2 + z^2)]
3444
+ sage: ith_to_zero_rotation_matrix(v, 2) * v
3445
+ (x, y^2/sqrt(y^2 + z^2) + z^2/sqrt(y^2 + z^2), 0)
3446
+
3447
+ TESTS::
3448
+
3449
+ sage: ith_to_zero_rotation_matrix((1,0,0), 0)
3450
+ [ 0 0 -1]
3451
+ [ 0 1 0]
3452
+ [ 1 0 0]
3453
+ sage: ith_to_zero_rotation_matrix((1,0,0), 1)
3454
+ [1 0 0]
3455
+ [0 1 0]
3456
+ [0 0 1]
3457
+ sage: ith_to_zero_rotation_matrix((1,0,0), 2)
3458
+ [1 0 0]
3459
+ [0 1 0]
3460
+ [0 0 1]
3461
+
3462
+ AUTHORS:
3463
+
3464
+ Sébastien Labbé (April 2010)
3465
+ """
3466
+ if ring is not None:
3467
+ # coerce the vector so that computations
3468
+ # are done in that ring
3469
+ v = vector(ring, v)
3470
+ dim = len(v)
3471
+ i = i % dim
3472
+ j = (i - 1) % dim
3473
+ a, b = v[j], v[i]
3474
+ if b == 0:
3475
+ return identity_matrix(dim, sparse=True)
3476
+ from sage.misc.functional import sqrt
3477
+ norm = sqrt(a * a + b * b)
3478
+ aa = a / norm
3479
+ bb = b / norm
3480
+ entries = {(k, k): 1 for k in range(dim)}
3481
+ entries.update({(j, j): aa, (j, i): bb, (i, j): -bb, (i, i): aa})
3482
+ return matrix(entries, nrows=dim, base_ring=ring)
3483
+
3484
+
3485
+ @matrix_method
3486
+ def hilbert(dim, ring=QQ):
3487
+ r"""
3488
+ Return a Hilbert matrix of the given dimension.
3489
+
3490
+ The `n` dimensional Hilbert matrix is a square matrix with entries being
3491
+ unit fractions,
3492
+
3493
+ .. MATH::
3494
+
3495
+ H_{ij} = \frac{1}{i+j-1},\qquad i, j = 1,\ldots, n.
3496
+
3497
+ For more information see the :wikipedia:`Hilbert_matrix`.
3498
+
3499
+ INPUT:
3500
+
3501
+ - ``dim`` -- integer; the dimension of the Hilbert matrix
3502
+
3503
+ - ``ring`` -- base ring (default: `\QQ`) of the resulting matrix
3504
+
3505
+ EXAMPLES::
3506
+
3507
+ sage: matrix.hilbert(5)
3508
+ [ 1 1/2 1/3 1/4 1/5]
3509
+ [1/2 1/3 1/4 1/5 1/6]
3510
+ [1/3 1/4 1/5 1/6 1/7]
3511
+ [1/4 1/5 1/6 1/7 1/8]
3512
+ [1/5 1/6 1/7 1/8 1/9]
3513
+ """
3514
+ def entries(i, j):
3515
+ return ZZ.one() / (i + j + 1)
3516
+ return matrix(entries, nrows=dim, ncols=dim, base_ring=ring)
3517
+
3518
+
3519
+ @matrix_method
3520
+ def vandermonde(v, ring=None):
3521
+ r"""
3522
+ Return a Vandermonde matrix of the given vector.
3523
+
3524
+ The `n` dimensional Vandermonde matrix is a square matrix with columns
3525
+ being the powers of a given vector `v`,
3526
+
3527
+ .. MATH::
3528
+
3529
+ V_{ij} = v_i^{j-1},\qquad i, j = 1,\ldots, n.
3530
+
3531
+ For more information see the :wikipedia:`Vandermonde_matrix`.
3532
+
3533
+ INPUT:
3534
+
3535
+ - ``v`` -- vector, the second column of the Vandermonde matrix
3536
+
3537
+ - ``ring`` -- base ring (default: ``None``) of the resulting matrix
3538
+
3539
+ EXAMPLES:
3540
+
3541
+ A Vandermonde matrix of order three over the symbolic ring::
3542
+
3543
+ sage: matrix.vandermonde(SR.var(['x0', 'x1', 'x2'])) # needs sage.symbolic
3544
+ [ 1 x0 x0^2]
3545
+ [ 1 x1 x1^2]
3546
+ [ 1 x2 x2^2]
3547
+ """
3548
+ def entries(i, j):
3549
+ return v[i]**j
3550
+ return matrix(entries, nrows=len(v), ncols=len(v), base_ring=ring)
3551
+
3552
+
3553
+ @matrix_method
3554
+ def toeplitz(c, r, ring=None):
3555
+ r"""
3556
+ Return a Toeplitz matrix of given first column and first row.
3557
+
3558
+ In a Toeplitz matrix, each descending diagonal from left to right is
3559
+ constant, such that:
3560
+
3561
+ .. MATH:: T_{i,j} = T_{i+1, j+1}.
3562
+
3563
+ For more information see the :wikipedia:`Toeplitz_matrix`.
3564
+
3565
+ INPUT:
3566
+
3567
+ - ``c`` -- vector, first column of the Toeplitz matrix
3568
+
3569
+ - ``r`` -- vector, first row of the Toeplitz matrix, counting from the
3570
+ second column
3571
+
3572
+ - ``ring`` -- base ring (default: ``None``) of the resulting matrix
3573
+
3574
+ EXAMPLES:
3575
+
3576
+ A rectangular Toeplitz matrix::
3577
+
3578
+ sage: matrix.toeplitz([1..4], [5..6])
3579
+ [1 5 6]
3580
+ [2 1 5]
3581
+ [3 2 1]
3582
+ [4 3 2]
3583
+
3584
+ The following `N\times N` Toeplitz matrix arises in the discretization of
3585
+ boundary value problems::
3586
+
3587
+ sage: N = 4
3588
+ sage: matrix.toeplitz([-2, 1] + [0]*(N-2), [1] + [0]*(N-2))
3589
+ [-2 1 0 0]
3590
+ [ 1 -2 1 0]
3591
+ [ 0 1 -2 1]
3592
+ [ 0 0 1 -2]
3593
+ """
3594
+ def entries(i, j):
3595
+ return c[i - j] if i >= j else r[j - i - 1]
3596
+ return matrix(entries, nrows=len(c), ncols=len(r)+1, base_ring=ring)
3597
+
3598
+
3599
+ @matrix_method
3600
+ def hankel(c, r=None, ring=None):
3601
+ r"""
3602
+ Return a Hankel matrix of given first column and whose elements are zero
3603
+ below the first anti-diagonal.
3604
+
3605
+ The Hankel matrix is symmetric and constant across the anti-diagonals,
3606
+ with elements
3607
+
3608
+ .. MATH::
3609
+
3610
+ H_{ij} = v_{i+j-1},\qquad i = 1,\ldots, m,~j = 1,\ldots, n,
3611
+
3612
+ where the vector `v_i = c_i` for `i = 1,\ldots, m` and `v_{m+i} = r_i` for
3613
+ `i = 1, \ldots, n-1` completely determines the Hankel matrix. If the last
3614
+ row, `r`, is not given, the Hankel matrix is square by default and `r = 0`.
3615
+ For more information see the :wikipedia:`Hankel_matrix`.
3616
+
3617
+ INPUT:
3618
+
3619
+ - ``c`` -- vector, first column of the Hankel matrix
3620
+
3621
+ - ``r`` -- vector (default: ``None``); last row of the Hankel matrix, from
3622
+ the second to the last column
3623
+
3624
+ - ``ring`` -- base ring (default: ``None``) of the resulting matrix
3625
+
3626
+ EXAMPLES:
3627
+
3628
+ A Hankel matrix with symbolic entries::
3629
+
3630
+ sage: matrix.hankel(SR.var('a, b, c, d, e')) # needs sage.symbolic
3631
+ [a b c d e]
3632
+ [b c d e 0]
3633
+ [c d e 0 0]
3634
+ [d e 0 0 0]
3635
+ [e 0 0 0 0]
3636
+
3637
+ We can also pass the elements of the last row, starting at the second column::
3638
+
3639
+ sage: matrix.hankel(SR.var('a, b, c, d, e'), SR.var('f, g, h, i')) # needs sage.symbolic
3640
+ [a b c d e]
3641
+ [b c d e f]
3642
+ [c d e f g]
3643
+ [d e f g h]
3644
+ [e f g h i]
3645
+
3646
+ A third order Hankel matrix in the integers::
3647
+
3648
+ sage: matrix.hankel([1, 2, 3])
3649
+ [1 2 3]
3650
+ [2 3 0]
3651
+ [3 0 0]
3652
+
3653
+ The second argument allows to customize the last row::
3654
+
3655
+ sage: matrix.hankel([1..3], [7..10])
3656
+ [ 1 2 3 7 8]
3657
+ [ 2 3 7 8 9]
3658
+ [ 3 7 8 9 10]
3659
+ """
3660
+ m = len(c)
3661
+ r = [0] * (m - 1) if r is None else list(r)
3662
+ n = len(r)
3663
+
3664
+ def entries(i):
3665
+ return c[i] if i < m else r[i - m]
3666
+ return matrix(lambda i, j: entries(i + j), nrows=m, ncols=n + 1, base_ring=ring)