passagemath-categories 10.6.32__cp314-cp314t-musllinux_1_2_aarch64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (719) hide show
  1. passagemath_categories-10.6.32.dist-info/METADATA +156 -0
  2. passagemath_categories-10.6.32.dist-info/RECORD +719 -0
  3. passagemath_categories-10.6.32.dist-info/WHEEL +5 -0
  4. passagemath_categories-10.6.32.dist-info/top_level.txt +2 -0
  5. passagemath_categories.libs/libgcc_s-2d945d6c.so.1 +0 -0
  6. passagemath_categories.libs/libgmp-28992bcb.so.10.5.0 +0 -0
  7. passagemath_categories.libs/libstdc++-85f2cd6d.so.6.0.33 +0 -0
  8. sage/all__sagemath_categories.py +28 -0
  9. sage/arith/all.py +38 -0
  10. sage/arith/constants.pxd +27 -0
  11. sage/arith/functions.cpython-314t-aarch64-linux-musl.so +0 -0
  12. sage/arith/functions.pxd +4 -0
  13. sage/arith/functions.pyx +221 -0
  14. sage/arith/misc.py +6552 -0
  15. sage/arith/multi_modular.cpython-314t-aarch64-linux-musl.so +0 -0
  16. sage/arith/multi_modular.pxd +39 -0
  17. sage/arith/multi_modular.pyx +994 -0
  18. sage/arith/rational_reconstruction.cpython-314t-aarch64-linux-musl.so +0 -0
  19. sage/arith/rational_reconstruction.pxd +4 -0
  20. sage/arith/rational_reconstruction.pyx +115 -0
  21. sage/arith/srange.cpython-314t-aarch64-linux-musl.so +0 -0
  22. sage/arith/srange.pyx +571 -0
  23. sage/calculus/all__sagemath_categories.py +2 -0
  24. sage/calculus/functional.py +481 -0
  25. sage/calculus/functions.py +151 -0
  26. sage/categories/additive_groups.py +73 -0
  27. sage/categories/additive_magmas.py +1044 -0
  28. sage/categories/additive_monoids.py +114 -0
  29. sage/categories/additive_semigroups.py +184 -0
  30. sage/categories/affine_weyl_groups.py +238 -0
  31. sage/categories/algebra_ideals.py +95 -0
  32. sage/categories/algebra_modules.py +96 -0
  33. sage/categories/algebras.py +349 -0
  34. sage/categories/algebras_with_basis.py +377 -0
  35. sage/categories/all.py +160 -0
  36. sage/categories/aperiodic_semigroups.py +29 -0
  37. sage/categories/associative_algebras.py +47 -0
  38. sage/categories/bialgebras.py +101 -0
  39. sage/categories/bialgebras_with_basis.py +414 -0
  40. sage/categories/bimodules.py +206 -0
  41. sage/categories/chain_complexes.py +268 -0
  42. sage/categories/classical_crystals.py +480 -0
  43. sage/categories/coalgebras.py +405 -0
  44. sage/categories/coalgebras_with_basis.py +232 -0
  45. sage/categories/coercion_methods.cpython-314t-aarch64-linux-musl.so +0 -0
  46. sage/categories/coercion_methods.pyx +52 -0
  47. sage/categories/commutative_additive_groups.py +104 -0
  48. sage/categories/commutative_additive_monoids.py +45 -0
  49. sage/categories/commutative_additive_semigroups.py +48 -0
  50. sage/categories/commutative_algebra_ideals.py +87 -0
  51. sage/categories/commutative_algebras.py +94 -0
  52. sage/categories/commutative_ring_ideals.py +58 -0
  53. sage/categories/commutative_rings.py +736 -0
  54. sage/categories/complete_discrete_valuation.py +293 -0
  55. sage/categories/complex_reflection_groups.py +145 -0
  56. sage/categories/complex_reflection_or_generalized_coxeter_groups.py +1249 -0
  57. sage/categories/coxeter_group_algebras.py +186 -0
  58. sage/categories/coxeter_groups.py +3402 -0
  59. sage/categories/crystals.py +2628 -0
  60. sage/categories/cw_complexes.py +216 -0
  61. sage/categories/dedekind_domains.py +137 -0
  62. sage/categories/discrete_valuation.py +325 -0
  63. sage/categories/distributive_magmas_and_additive_magmas.py +100 -0
  64. sage/categories/division_rings.py +114 -0
  65. sage/categories/domains.py +95 -0
  66. sage/categories/drinfeld_modules.py +789 -0
  67. sage/categories/dual.py +42 -0
  68. sage/categories/enumerated_sets.py +1146 -0
  69. sage/categories/euclidean_domains.py +271 -0
  70. sage/categories/examples/algebras_with_basis.py +102 -0
  71. sage/categories/examples/all.py +1 -0
  72. sage/categories/examples/commutative_additive_monoids.py +130 -0
  73. sage/categories/examples/commutative_additive_semigroups.py +199 -0
  74. sage/categories/examples/coxeter_groups.py +8 -0
  75. sage/categories/examples/crystals.py +236 -0
  76. sage/categories/examples/cw_complexes.py +163 -0
  77. sage/categories/examples/facade_sets.py +187 -0
  78. sage/categories/examples/filtered_algebras_with_basis.py +204 -0
  79. sage/categories/examples/filtered_modules_with_basis.py +154 -0
  80. sage/categories/examples/finite_coxeter_groups.py +252 -0
  81. sage/categories/examples/finite_dimensional_algebras_with_basis.py +148 -0
  82. sage/categories/examples/finite_dimensional_lie_algebras_with_basis.py +495 -0
  83. sage/categories/examples/finite_enumerated_sets.py +208 -0
  84. sage/categories/examples/finite_monoids.py +150 -0
  85. sage/categories/examples/finite_semigroups.py +190 -0
  86. sage/categories/examples/finite_weyl_groups.py +191 -0
  87. sage/categories/examples/graded_connected_hopf_algebras_with_basis.py +152 -0
  88. sage/categories/examples/graded_modules_with_basis.py +168 -0
  89. sage/categories/examples/graphs.py +122 -0
  90. sage/categories/examples/hopf_algebras_with_basis.py +145 -0
  91. sage/categories/examples/infinite_enumerated_sets.py +190 -0
  92. sage/categories/examples/lie_algebras.py +352 -0
  93. sage/categories/examples/lie_algebras_with_basis.py +196 -0
  94. sage/categories/examples/magmas.py +162 -0
  95. sage/categories/examples/manifolds.py +94 -0
  96. sage/categories/examples/monoids.py +144 -0
  97. sage/categories/examples/posets.py +178 -0
  98. sage/categories/examples/semigroups.py +580 -0
  99. sage/categories/examples/semigroups_cython.cpython-314t-aarch64-linux-musl.so +0 -0
  100. sage/categories/examples/semigroups_cython.pyx +221 -0
  101. sage/categories/examples/semirings.py +249 -0
  102. sage/categories/examples/sets_cat.py +706 -0
  103. sage/categories/examples/sets_with_grading.py +101 -0
  104. sage/categories/examples/with_realizations.py +542 -0
  105. sage/categories/fields.py +991 -0
  106. sage/categories/filtered_algebras.py +63 -0
  107. sage/categories/filtered_algebras_with_basis.py +548 -0
  108. sage/categories/filtered_hopf_algebras_with_basis.py +138 -0
  109. sage/categories/filtered_modules.py +210 -0
  110. sage/categories/filtered_modules_with_basis.py +1209 -0
  111. sage/categories/finite_complex_reflection_groups.py +1506 -0
  112. sage/categories/finite_coxeter_groups.py +1138 -0
  113. sage/categories/finite_crystals.py +103 -0
  114. sage/categories/finite_dimensional_algebras_with_basis.py +1860 -0
  115. sage/categories/finite_dimensional_bialgebras_with_basis.py +33 -0
  116. sage/categories/finite_dimensional_coalgebras_with_basis.py +33 -0
  117. sage/categories/finite_dimensional_graded_lie_algebras_with_basis.py +231 -0
  118. sage/categories/finite_dimensional_hopf_algebras_with_basis.py +38 -0
  119. sage/categories/finite_dimensional_lie_algebras_with_basis.py +2774 -0
  120. sage/categories/finite_dimensional_modules_with_basis.py +1407 -0
  121. sage/categories/finite_dimensional_nilpotent_lie_algebras_with_basis.py +167 -0
  122. sage/categories/finite_dimensional_semisimple_algebras_with_basis.py +270 -0
  123. sage/categories/finite_enumerated_sets.py +769 -0
  124. sage/categories/finite_fields.py +252 -0
  125. sage/categories/finite_groups.py +256 -0
  126. sage/categories/finite_lattice_posets.py +242 -0
  127. sage/categories/finite_monoids.py +316 -0
  128. sage/categories/finite_permutation_groups.py +339 -0
  129. sage/categories/finite_posets.py +1994 -0
  130. sage/categories/finite_semigroups.py +136 -0
  131. sage/categories/finite_sets.py +93 -0
  132. sage/categories/finite_weyl_groups.py +39 -0
  133. sage/categories/finitely_generated_lambda_bracket_algebras.py +112 -0
  134. sage/categories/finitely_generated_lie_conformal_algebras.py +114 -0
  135. sage/categories/finitely_generated_magmas.py +57 -0
  136. sage/categories/finitely_generated_semigroups.py +214 -0
  137. sage/categories/function_fields.py +76 -0
  138. sage/categories/g_sets.py +77 -0
  139. sage/categories/gcd_domains.py +65 -0
  140. sage/categories/generalized_coxeter_groups.py +94 -0
  141. sage/categories/graded_algebras.py +85 -0
  142. sage/categories/graded_algebras_with_basis.py +258 -0
  143. sage/categories/graded_bialgebras.py +32 -0
  144. sage/categories/graded_bialgebras_with_basis.py +32 -0
  145. sage/categories/graded_coalgebras.py +65 -0
  146. sage/categories/graded_coalgebras_with_basis.py +51 -0
  147. sage/categories/graded_hopf_algebras.py +41 -0
  148. sage/categories/graded_hopf_algebras_with_basis.py +169 -0
  149. sage/categories/graded_lie_algebras.py +91 -0
  150. sage/categories/graded_lie_algebras_with_basis.py +44 -0
  151. sage/categories/graded_lie_conformal_algebras.py +74 -0
  152. sage/categories/graded_modules.py +133 -0
  153. sage/categories/graded_modules_with_basis.py +329 -0
  154. sage/categories/graphs.py +138 -0
  155. sage/categories/group_algebras.py +430 -0
  156. sage/categories/groupoid.py +94 -0
  157. sage/categories/groups.py +667 -0
  158. sage/categories/h_trivial_semigroups.py +64 -0
  159. sage/categories/hecke_modules.py +185 -0
  160. sage/categories/highest_weight_crystals.py +980 -0
  161. sage/categories/hopf_algebras.py +219 -0
  162. sage/categories/hopf_algebras_with_basis.py +309 -0
  163. sage/categories/infinite_enumerated_sets.py +115 -0
  164. sage/categories/integral_domains.py +203 -0
  165. sage/categories/j_trivial_semigroups.py +29 -0
  166. sage/categories/kac_moody_algebras.py +82 -0
  167. sage/categories/kahler_algebras.py +203 -0
  168. sage/categories/l_trivial_semigroups.py +63 -0
  169. sage/categories/lambda_bracket_algebras.py +280 -0
  170. sage/categories/lambda_bracket_algebras_with_basis.py +107 -0
  171. sage/categories/lattice_posets.py +89 -0
  172. sage/categories/left_modules.py +49 -0
  173. sage/categories/lie_algebras.py +1070 -0
  174. sage/categories/lie_algebras_with_basis.py +261 -0
  175. sage/categories/lie_conformal_algebras.py +350 -0
  176. sage/categories/lie_conformal_algebras_with_basis.py +147 -0
  177. sage/categories/lie_groups.py +73 -0
  178. sage/categories/loop_crystals.py +1290 -0
  179. sage/categories/magmas.py +1189 -0
  180. sage/categories/magmas_and_additive_magmas.py +149 -0
  181. sage/categories/magmatic_algebras.py +365 -0
  182. sage/categories/manifolds.py +352 -0
  183. sage/categories/matrix_algebras.py +40 -0
  184. sage/categories/metric_spaces.py +387 -0
  185. sage/categories/modular_abelian_varieties.py +78 -0
  186. sage/categories/modules.py +989 -0
  187. sage/categories/modules_with_basis.py +2794 -0
  188. sage/categories/monoid_algebras.py +38 -0
  189. sage/categories/monoids.py +739 -0
  190. sage/categories/noetherian_rings.py +87 -0
  191. sage/categories/number_fields.py +242 -0
  192. sage/categories/ore_modules.py +189 -0
  193. sage/categories/partially_ordered_monoids.py +49 -0
  194. sage/categories/permutation_groups.py +63 -0
  195. sage/categories/pointed_sets.py +42 -0
  196. sage/categories/polyhedra.py +74 -0
  197. sage/categories/poor_man_map.py +270 -0
  198. sage/categories/posets.py +722 -0
  199. sage/categories/principal_ideal_domains.py +270 -0
  200. sage/categories/quantum_group_representations.py +543 -0
  201. sage/categories/quotient_fields.py +728 -0
  202. sage/categories/r_trivial_semigroups.py +45 -0
  203. sage/categories/regular_crystals.py +898 -0
  204. sage/categories/regular_supercrystals.py +170 -0
  205. sage/categories/right_modules.py +49 -0
  206. sage/categories/ring_ideals.py +74 -0
  207. sage/categories/rings.py +1904 -0
  208. sage/categories/rngs.py +175 -0
  209. sage/categories/schemes.py +393 -0
  210. sage/categories/semigroups.py +1060 -0
  211. sage/categories/semirings.py +71 -0
  212. sage/categories/semisimple_algebras.py +114 -0
  213. sage/categories/sets_with_grading.py +235 -0
  214. sage/categories/shephard_groups.py +43 -0
  215. sage/categories/signed_tensor.py +120 -0
  216. sage/categories/simplicial_complexes.py +134 -0
  217. sage/categories/simplicial_sets.py +1206 -0
  218. sage/categories/super_algebras.py +149 -0
  219. sage/categories/super_algebras_with_basis.py +144 -0
  220. sage/categories/super_hopf_algebras_with_basis.py +126 -0
  221. sage/categories/super_lie_conformal_algebras.py +193 -0
  222. sage/categories/super_modules.py +229 -0
  223. sage/categories/super_modules_with_basis.py +193 -0
  224. sage/categories/supercommutative_algebras.py +99 -0
  225. sage/categories/supercrystals.py +406 -0
  226. sage/categories/tensor.py +110 -0
  227. sage/categories/topological_spaces.py +170 -0
  228. sage/categories/triangular_kac_moody_algebras.py +439 -0
  229. sage/categories/tutorial.py +58 -0
  230. sage/categories/unique_factorization_domains.py +318 -0
  231. sage/categories/unital_algebras.py +426 -0
  232. sage/categories/vector_bundles.py +159 -0
  233. sage/categories/vector_spaces.py +357 -0
  234. sage/categories/weyl_groups.py +853 -0
  235. sage/combinat/all__sagemath_categories.py +34 -0
  236. sage/combinat/backtrack.py +180 -0
  237. sage/combinat/combinat.py +2269 -0
  238. sage/combinat/combinat_cython.cpython-314t-aarch64-linux-musl.so +0 -0
  239. sage/combinat/combinat_cython.pxd +6 -0
  240. sage/combinat/combinat_cython.pyx +390 -0
  241. sage/combinat/combination.py +796 -0
  242. sage/combinat/combinatorial_map.py +416 -0
  243. sage/combinat/composition.py +2192 -0
  244. sage/combinat/dlx.py +510 -0
  245. sage/combinat/integer_lists/__init__.py +7 -0
  246. sage/combinat/integer_lists/base.cpython-314t-aarch64-linux-musl.so +0 -0
  247. sage/combinat/integer_lists/base.pxd +16 -0
  248. sage/combinat/integer_lists/base.pyx +713 -0
  249. sage/combinat/integer_lists/invlex.cpython-314t-aarch64-linux-musl.so +0 -0
  250. sage/combinat/integer_lists/invlex.pxd +4 -0
  251. sage/combinat/integer_lists/invlex.pyx +1650 -0
  252. sage/combinat/integer_lists/lists.py +328 -0
  253. sage/combinat/integer_lists/nn.py +48 -0
  254. sage/combinat/integer_vector.py +1818 -0
  255. sage/combinat/integer_vector_weighted.py +413 -0
  256. sage/combinat/matrices/all__sagemath_categories.py +5 -0
  257. sage/combinat/matrices/dancing_links.cpython-314t-aarch64-linux-musl.so +0 -0
  258. sage/combinat/matrices/dancing_links.pyx +1159 -0
  259. sage/combinat/matrices/dancing_links_c.h +380 -0
  260. sage/combinat/matrices/dlxcpp.py +136 -0
  261. sage/combinat/partition.py +10070 -0
  262. sage/combinat/partitions.cpython-314t-aarch64-linux-musl.so +0 -0
  263. sage/combinat/partitions.pyx +743 -0
  264. sage/combinat/permutation.py +10168 -0
  265. sage/combinat/permutation_cython.cpython-314t-aarch64-linux-musl.so +0 -0
  266. sage/combinat/permutation_cython.pxd +11 -0
  267. sage/combinat/permutation_cython.pyx +407 -0
  268. sage/combinat/q_analogues.py +1090 -0
  269. sage/combinat/ranker.py +268 -0
  270. sage/combinat/subset.py +1561 -0
  271. sage/combinat/subsets_hereditary.py +202 -0
  272. sage/combinat/subsets_pairwise.py +184 -0
  273. sage/combinat/tools.py +63 -0
  274. sage/combinat/tuple.py +348 -0
  275. sage/data_structures/all.py +2 -0
  276. sage/data_structures/all__sagemath_categories.py +2 -0
  277. sage/data_structures/binary_matrix.pxd +138 -0
  278. sage/data_structures/binary_search.cpython-314t-aarch64-linux-musl.so +0 -0
  279. sage/data_structures/binary_search.pxd +3 -0
  280. sage/data_structures/binary_search.pyx +66 -0
  281. sage/data_structures/bitset.cpython-314t-aarch64-linux-musl.so +0 -0
  282. sage/data_structures/bitset.pxd +40 -0
  283. sage/data_structures/bitset.pyx +2385 -0
  284. sage/data_structures/bitset_base.cpython-314t-aarch64-linux-musl.so +0 -0
  285. sage/data_structures/bitset_base.pxd +926 -0
  286. sage/data_structures/bitset_base.pyx +117 -0
  287. sage/data_structures/bitset_intrinsics.h +487 -0
  288. sage/data_structures/blas_dict.cpython-314t-aarch64-linux-musl.so +0 -0
  289. sage/data_structures/blas_dict.pxd +12 -0
  290. sage/data_structures/blas_dict.pyx +469 -0
  291. sage/data_structures/list_of_pairs.cpython-314t-aarch64-linux-musl.so +0 -0
  292. sage/data_structures/list_of_pairs.pxd +16 -0
  293. sage/data_structures/list_of_pairs.pyx +122 -0
  294. sage/data_structures/mutable_poset.py +3312 -0
  295. sage/data_structures/pairing_heap.cpython-314t-aarch64-linux-musl.so +0 -0
  296. sage/data_structures/pairing_heap.h +346 -0
  297. sage/data_structures/pairing_heap.pxd +88 -0
  298. sage/data_structures/pairing_heap.pyx +1464 -0
  299. sage/data_structures/sparse_bitset.pxd +62 -0
  300. sage/data_structures/stream.py +5070 -0
  301. sage/databases/all__sagemath_categories.py +7 -0
  302. sage/databases/sql_db.py +2236 -0
  303. sage/ext/all__sagemath_categories.py +3 -0
  304. sage/ext/fast_callable.cpython-314t-aarch64-linux-musl.so +0 -0
  305. sage/ext/fast_callable.pxd +4 -0
  306. sage/ext/fast_callable.pyx +2746 -0
  307. sage/ext/fast_eval.cpython-314t-aarch64-linux-musl.so +0 -0
  308. sage/ext/fast_eval.pxd +1 -0
  309. sage/ext/fast_eval.pyx +102 -0
  310. sage/ext/interpreters/__init__.py +1 -0
  311. sage/ext/interpreters/all__sagemath_categories.py +2 -0
  312. sage/ext/interpreters/wrapper_el.cpython-314t-aarch64-linux-musl.so +0 -0
  313. sage/ext/interpreters/wrapper_el.pxd +18 -0
  314. sage/ext/interpreters/wrapper_el.pyx +148 -0
  315. sage/ext/interpreters/wrapper_py.cpython-314t-aarch64-linux-musl.so +0 -0
  316. sage/ext/interpreters/wrapper_py.pxd +17 -0
  317. sage/ext/interpreters/wrapper_py.pyx +133 -0
  318. sage/functions/airy.py +937 -0
  319. sage/functions/all.py +97 -0
  320. sage/functions/bessel.py +2102 -0
  321. sage/functions/error.py +784 -0
  322. sage/functions/exp_integral.py +1529 -0
  323. sage/functions/gamma.py +1087 -0
  324. sage/functions/generalized.py +672 -0
  325. sage/functions/hyperbolic.py +747 -0
  326. sage/functions/hypergeometric.py +1156 -0
  327. sage/functions/jacobi.py +1705 -0
  328. sage/functions/log.py +1402 -0
  329. sage/functions/min_max.py +338 -0
  330. sage/functions/orthogonal_polys.py +3106 -0
  331. sage/functions/other.py +2303 -0
  332. sage/functions/piecewise.py +1505 -0
  333. sage/functions/prime_pi.cpython-314t-aarch64-linux-musl.so +0 -0
  334. sage/functions/prime_pi.pyx +262 -0
  335. sage/functions/special.py +1212 -0
  336. sage/functions/spike_function.py +278 -0
  337. sage/functions/transcendental.py +690 -0
  338. sage/functions/trig.py +1062 -0
  339. sage/functions/wigner.py +726 -0
  340. sage/geometry/abc.cpython-314t-aarch64-linux-musl.so +0 -0
  341. sage/geometry/abc.pyx +82 -0
  342. sage/geometry/all__sagemath_categories.py +1 -0
  343. sage/groups/all__sagemath_categories.py +11 -0
  344. sage/groups/generic.py +1733 -0
  345. sage/groups/groups_catalog.py +113 -0
  346. sage/groups/perm_gps/all__sagemath_categories.py +1 -0
  347. sage/groups/perm_gps/partn_ref/all.py +1 -0
  348. sage/groups/perm_gps/partn_ref/all__sagemath_categories.py +1 -0
  349. sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.cpython-314t-aarch64-linux-musl.so +0 -0
  350. sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pxd +52 -0
  351. sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx +906 -0
  352. sage/groups/perm_gps/partn_ref/canonical_augmentation.cpython-314t-aarch64-linux-musl.so +0 -0
  353. sage/groups/perm_gps/partn_ref/canonical_augmentation.pxd +85 -0
  354. sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx +534 -0
  355. sage/groups/perm_gps/partn_ref/data_structures.cpython-314t-aarch64-linux-musl.so +0 -0
  356. sage/groups/perm_gps/partn_ref/data_structures.pxd +576 -0
  357. sage/groups/perm_gps/partn_ref/data_structures.pyx +1792 -0
  358. sage/groups/perm_gps/partn_ref/double_coset.cpython-314t-aarch64-linux-musl.so +0 -0
  359. sage/groups/perm_gps/partn_ref/double_coset.pxd +45 -0
  360. sage/groups/perm_gps/partn_ref/double_coset.pyx +739 -0
  361. sage/groups/perm_gps/partn_ref/refinement_lists.cpython-314t-aarch64-linux-musl.so +0 -0
  362. sage/groups/perm_gps/partn_ref/refinement_lists.pxd +18 -0
  363. sage/groups/perm_gps/partn_ref/refinement_lists.pyx +82 -0
  364. sage/groups/perm_gps/partn_ref/refinement_python.cpython-314t-aarch64-linux-musl.so +0 -0
  365. sage/groups/perm_gps/partn_ref/refinement_python.pxd +16 -0
  366. sage/groups/perm_gps/partn_ref/refinement_python.pyx +564 -0
  367. sage/groups/perm_gps/partn_ref/refinement_sets.cpython-314t-aarch64-linux-musl.so +0 -0
  368. sage/groups/perm_gps/partn_ref/refinement_sets.pxd +60 -0
  369. sage/groups/perm_gps/partn_ref/refinement_sets.pyx +858 -0
  370. sage/interfaces/abc.py +140 -0
  371. sage/interfaces/all.py +58 -0
  372. sage/interfaces/all__sagemath_categories.py +1 -0
  373. sage/interfaces/expect.py +1643 -0
  374. sage/interfaces/interface.py +1682 -0
  375. sage/interfaces/process.cpython-314t-aarch64-linux-musl.so +0 -0
  376. sage/interfaces/process.pxd +5 -0
  377. sage/interfaces/process.pyx +288 -0
  378. sage/interfaces/quit.py +167 -0
  379. sage/interfaces/sage0.py +604 -0
  380. sage/interfaces/sagespawn.cpython-314t-aarch64-linux-musl.so +0 -0
  381. sage/interfaces/sagespawn.pyx +308 -0
  382. sage/interfaces/tab_completion.py +101 -0
  383. sage/misc/all__sagemath_categories.py +78 -0
  384. sage/misc/allocator.cpython-314t-aarch64-linux-musl.so +0 -0
  385. sage/misc/allocator.pxd +6 -0
  386. sage/misc/allocator.pyx +47 -0
  387. sage/misc/binary_tree.cpython-314t-aarch64-linux-musl.so +0 -0
  388. sage/misc/binary_tree.pxd +29 -0
  389. sage/misc/binary_tree.pyx +537 -0
  390. sage/misc/callable_dict.cpython-314t-aarch64-linux-musl.so +0 -0
  391. sage/misc/callable_dict.pyx +89 -0
  392. sage/misc/citation.cpython-314t-aarch64-linux-musl.so +0 -0
  393. sage/misc/citation.pyx +159 -0
  394. sage/misc/converting_dict.py +293 -0
  395. sage/misc/defaults.py +129 -0
  396. sage/misc/derivative.cpython-314t-aarch64-linux-musl.so +0 -0
  397. sage/misc/derivative.pyx +223 -0
  398. sage/misc/functional.py +2005 -0
  399. sage/misc/html.py +589 -0
  400. sage/misc/latex.py +2673 -0
  401. sage/misc/latex_macros.py +236 -0
  402. sage/misc/latex_standalone.py +1833 -0
  403. sage/misc/map_threaded.py +38 -0
  404. sage/misc/mathml.py +76 -0
  405. sage/misc/method_decorator.py +88 -0
  406. sage/misc/mrange.py +755 -0
  407. sage/misc/multireplace.py +41 -0
  408. sage/misc/object_multiplexer.py +92 -0
  409. sage/misc/parser.cpython-314t-aarch64-linux-musl.so +0 -0
  410. sage/misc/parser.pyx +1107 -0
  411. sage/misc/random_testing.py +264 -0
  412. sage/misc/rest_index_of_methods.py +377 -0
  413. sage/misc/search.cpython-314t-aarch64-linux-musl.so +0 -0
  414. sage/misc/search.pxd +2 -0
  415. sage/misc/search.pyx +68 -0
  416. sage/misc/stopgap.cpython-314t-aarch64-linux-musl.so +0 -0
  417. sage/misc/stopgap.pyx +95 -0
  418. sage/misc/table.py +853 -0
  419. sage/monoids/all__sagemath_categories.py +1 -0
  420. sage/monoids/indexed_free_monoid.py +1071 -0
  421. sage/monoids/monoid.py +82 -0
  422. sage/numerical/all__sagemath_categories.py +1 -0
  423. sage/numerical/backends/all__sagemath_categories.py +1 -0
  424. sage/numerical/backends/generic_backend.cpython-314t-aarch64-linux-musl.so +0 -0
  425. sage/numerical/backends/generic_backend.pxd +61 -0
  426. sage/numerical/backends/generic_backend.pyx +1893 -0
  427. sage/numerical/backends/generic_sdp_backend.cpython-314t-aarch64-linux-musl.so +0 -0
  428. sage/numerical/backends/generic_sdp_backend.pxd +38 -0
  429. sage/numerical/backends/generic_sdp_backend.pyx +755 -0
  430. sage/parallel/all.py +6 -0
  431. sage/parallel/decorate.py +575 -0
  432. sage/parallel/map_reduce.py +1997 -0
  433. sage/parallel/multiprocessing_sage.py +76 -0
  434. sage/parallel/ncpus.py +35 -0
  435. sage/parallel/parallelism.py +364 -0
  436. sage/parallel/reference.py +47 -0
  437. sage/parallel/use_fork.py +333 -0
  438. sage/rings/abc.cpython-314t-aarch64-linux-musl.so +0 -0
  439. sage/rings/abc.pxd +31 -0
  440. sage/rings/abc.pyx +526 -0
  441. sage/rings/algebraic_closure_finite_field.py +1154 -0
  442. sage/rings/all__sagemath_categories.py +91 -0
  443. sage/rings/big_oh.py +227 -0
  444. sage/rings/continued_fraction.py +2754 -0
  445. sage/rings/continued_fraction_gosper.py +220 -0
  446. sage/rings/factorint.cpython-314t-aarch64-linux-musl.so +0 -0
  447. sage/rings/factorint.pyx +295 -0
  448. sage/rings/fast_arith.cpython-314t-aarch64-linux-musl.so +0 -0
  449. sage/rings/fast_arith.pxd +21 -0
  450. sage/rings/fast_arith.pyx +535 -0
  451. sage/rings/finite_rings/all__sagemath_categories.py +9 -0
  452. sage/rings/finite_rings/conway_polynomials.py +542 -0
  453. sage/rings/finite_rings/element_base.cpython-314t-aarch64-linux-musl.so +0 -0
  454. sage/rings/finite_rings/element_base.pxd +12 -0
  455. sage/rings/finite_rings/element_base.pyx +1176 -0
  456. sage/rings/finite_rings/finite_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
  457. sage/rings/finite_rings/finite_field_base.pxd +7 -0
  458. sage/rings/finite_rings/finite_field_base.pyx +2171 -0
  459. sage/rings/finite_rings/finite_field_constructor.py +827 -0
  460. sage/rings/finite_rings/finite_field_prime_modn.py +372 -0
  461. sage/rings/finite_rings/galois_group.py +154 -0
  462. sage/rings/finite_rings/hom_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
  463. sage/rings/finite_rings/hom_finite_field.pxd +23 -0
  464. sage/rings/finite_rings/hom_finite_field.pyx +856 -0
  465. sage/rings/finite_rings/hom_prime_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
  466. sage/rings/finite_rings/hom_prime_finite_field.pxd +15 -0
  467. sage/rings/finite_rings/hom_prime_finite_field.pyx +164 -0
  468. sage/rings/finite_rings/homset.py +357 -0
  469. sage/rings/finite_rings/integer_mod.cpython-314t-aarch64-linux-musl.so +0 -0
  470. sage/rings/finite_rings/integer_mod.pxd +56 -0
  471. sage/rings/finite_rings/integer_mod.pyx +4586 -0
  472. sage/rings/finite_rings/integer_mod_limits.h +11 -0
  473. sage/rings/finite_rings/integer_mod_ring.py +2044 -0
  474. sage/rings/finite_rings/residue_field.cpython-314t-aarch64-linux-musl.so +0 -0
  475. sage/rings/finite_rings/residue_field.pxd +30 -0
  476. sage/rings/finite_rings/residue_field.pyx +1811 -0
  477. sage/rings/finite_rings/stdint.pxd +19 -0
  478. sage/rings/fraction_field.py +1452 -0
  479. sage/rings/fraction_field_element.cpython-314t-aarch64-linux-musl.so +0 -0
  480. sage/rings/fraction_field_element.pyx +1357 -0
  481. sage/rings/function_field/all.py +7 -0
  482. sage/rings/function_field/all__sagemath_categories.py +2 -0
  483. sage/rings/function_field/constructor.py +218 -0
  484. sage/rings/function_field/element.cpython-314t-aarch64-linux-musl.so +0 -0
  485. sage/rings/function_field/element.pxd +11 -0
  486. sage/rings/function_field/element.pyx +1008 -0
  487. sage/rings/function_field/element_rational.cpython-314t-aarch64-linux-musl.so +0 -0
  488. sage/rings/function_field/element_rational.pyx +513 -0
  489. sage/rings/function_field/extensions.py +230 -0
  490. sage/rings/function_field/function_field.py +1468 -0
  491. sage/rings/function_field/function_field_rational.py +1005 -0
  492. sage/rings/function_field/ideal.py +1155 -0
  493. sage/rings/function_field/ideal_rational.py +629 -0
  494. sage/rings/function_field/jacobian_base.py +826 -0
  495. sage/rings/function_field/jacobian_hess.py +1053 -0
  496. sage/rings/function_field/jacobian_khuri_makdisi.py +1027 -0
  497. sage/rings/function_field/maps.py +1039 -0
  498. sage/rings/function_field/order.py +281 -0
  499. sage/rings/function_field/order_basis.py +586 -0
  500. sage/rings/function_field/order_rational.py +576 -0
  501. sage/rings/function_field/place.py +426 -0
  502. sage/rings/function_field/place_rational.py +181 -0
  503. sage/rings/generic.py +320 -0
  504. sage/rings/homset.py +332 -0
  505. sage/rings/ideal.py +1885 -0
  506. sage/rings/ideal_monoid.py +215 -0
  507. sage/rings/infinity.py +1890 -0
  508. sage/rings/integer.cpython-314t-aarch64-linux-musl.so +0 -0
  509. sage/rings/integer.pxd +45 -0
  510. sage/rings/integer.pyx +7874 -0
  511. sage/rings/integer_ring.cpython-314t-aarch64-linux-musl.so +0 -0
  512. sage/rings/integer_ring.pxd +8 -0
  513. sage/rings/integer_ring.pyx +1693 -0
  514. sage/rings/laurent_series_ring.py +931 -0
  515. sage/rings/laurent_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
  516. sage/rings/laurent_series_ring_element.pxd +11 -0
  517. sage/rings/laurent_series_ring_element.pyx +1927 -0
  518. sage/rings/lazy_series.py +7815 -0
  519. sage/rings/lazy_series_ring.py +4356 -0
  520. sage/rings/localization.py +1043 -0
  521. sage/rings/morphism.cpython-314t-aarch64-linux-musl.so +0 -0
  522. sage/rings/morphism.pxd +39 -0
  523. sage/rings/morphism.pyx +3299 -0
  524. sage/rings/multi_power_series_ring.py +1145 -0
  525. sage/rings/multi_power_series_ring_element.py +2184 -0
  526. sage/rings/noncommutative_ideals.cpython-314t-aarch64-linux-musl.so +0 -0
  527. sage/rings/noncommutative_ideals.pyx +423 -0
  528. sage/rings/number_field/all__sagemath_categories.py +1 -0
  529. sage/rings/number_field/number_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
  530. sage/rings/number_field/number_field_base.pxd +8 -0
  531. sage/rings/number_field/number_field_base.pyx +507 -0
  532. sage/rings/number_field/number_field_element_base.cpython-314t-aarch64-linux-musl.so +0 -0
  533. sage/rings/number_field/number_field_element_base.pxd +6 -0
  534. sage/rings/number_field/number_field_element_base.pyx +36 -0
  535. sage/rings/number_field/number_field_ideal.py +3550 -0
  536. sage/rings/padics/all__sagemath_categories.py +4 -0
  537. sage/rings/padics/local_generic.py +1670 -0
  538. sage/rings/padics/local_generic_element.cpython-314t-aarch64-linux-musl.so +0 -0
  539. sage/rings/padics/local_generic_element.pxd +5 -0
  540. sage/rings/padics/local_generic_element.pyx +1017 -0
  541. sage/rings/padics/misc.py +256 -0
  542. sage/rings/padics/padic_generic.py +1911 -0
  543. sage/rings/padics/pow_computer.cpython-314t-aarch64-linux-musl.so +0 -0
  544. sage/rings/padics/pow_computer.pxd +38 -0
  545. sage/rings/padics/pow_computer.pyx +671 -0
  546. sage/rings/padics/precision_error.py +24 -0
  547. sage/rings/polynomial/all__sagemath_categories.py +25 -0
  548. sage/rings/polynomial/commutative_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
  549. sage/rings/polynomial/commutative_polynomial.pxd +6 -0
  550. sage/rings/polynomial/commutative_polynomial.pyx +24 -0
  551. sage/rings/polynomial/cyclotomic.cpython-314t-aarch64-linux-musl.so +0 -0
  552. sage/rings/polynomial/cyclotomic.pyx +404 -0
  553. sage/rings/polynomial/flatten.py +711 -0
  554. sage/rings/polynomial/ideal.py +102 -0
  555. sage/rings/polynomial/infinite_polynomial_element.py +1768 -0
  556. sage/rings/polynomial/infinite_polynomial_ring.py +1653 -0
  557. sage/rings/polynomial/laurent_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
  558. sage/rings/polynomial/laurent_polynomial.pxd +18 -0
  559. sage/rings/polynomial/laurent_polynomial.pyx +2190 -0
  560. sage/rings/polynomial/laurent_polynomial_ideal.py +590 -0
  561. sage/rings/polynomial/laurent_polynomial_ring.py +832 -0
  562. sage/rings/polynomial/laurent_polynomial_ring_base.py +708 -0
  563. sage/rings/polynomial/multi_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
  564. sage/rings/polynomial/multi_polynomial.pxd +12 -0
  565. sage/rings/polynomial/multi_polynomial.pyx +3082 -0
  566. sage/rings/polynomial/multi_polynomial_element.py +2570 -0
  567. sage/rings/polynomial/multi_polynomial_ideal.py +5771 -0
  568. sage/rings/polynomial/multi_polynomial_ring.py +947 -0
  569. sage/rings/polynomial/multi_polynomial_ring_base.cpython-314t-aarch64-linux-musl.so +0 -0
  570. sage/rings/polynomial/multi_polynomial_ring_base.pxd +15 -0
  571. sage/rings/polynomial/multi_polynomial_ring_base.pyx +1855 -0
  572. sage/rings/polynomial/multi_polynomial_sequence.py +2204 -0
  573. sage/rings/polynomial/polydict.cpython-314t-aarch64-linux-musl.so +0 -0
  574. sage/rings/polynomial/polydict.pxd +45 -0
  575. sage/rings/polynomial/polydict.pyx +2701 -0
  576. sage/rings/polynomial/polynomial_compiled.cpython-314t-aarch64-linux-musl.so +0 -0
  577. sage/rings/polynomial/polynomial_compiled.pxd +59 -0
  578. sage/rings/polynomial/polynomial_compiled.pyx +509 -0
  579. sage/rings/polynomial/polynomial_element.cpython-314t-aarch64-linux-musl.so +0 -0
  580. sage/rings/polynomial/polynomial_element.pxd +64 -0
  581. sage/rings/polynomial/polynomial_element.pyx +13255 -0
  582. sage/rings/polynomial/polynomial_element_generic.py +1637 -0
  583. sage/rings/polynomial/polynomial_fateman.py +97 -0
  584. sage/rings/polynomial/polynomial_quotient_ring.py +2465 -0
  585. sage/rings/polynomial/polynomial_quotient_ring_element.py +779 -0
  586. sage/rings/polynomial/polynomial_ring.py +3784 -0
  587. sage/rings/polynomial/polynomial_ring_constructor.py +1051 -0
  588. sage/rings/polynomial/polynomial_ring_homomorphism.cpython-314t-aarch64-linux-musl.so +0 -0
  589. sage/rings/polynomial/polynomial_ring_homomorphism.pxd +5 -0
  590. sage/rings/polynomial/polynomial_ring_homomorphism.pyx +121 -0
  591. sage/rings/polynomial/polynomial_singular_interface.py +549 -0
  592. sage/rings/polynomial/symmetric_ideal.py +989 -0
  593. sage/rings/polynomial/symmetric_reduction.cpython-314t-aarch64-linux-musl.so +0 -0
  594. sage/rings/polynomial/symmetric_reduction.pxd +8 -0
  595. sage/rings/polynomial/symmetric_reduction.pyx +669 -0
  596. sage/rings/polynomial/term_order.py +2279 -0
  597. sage/rings/polynomial/toy_buchberger.py +449 -0
  598. sage/rings/polynomial/toy_d_basis.py +387 -0
  599. sage/rings/polynomial/toy_variety.py +362 -0
  600. sage/rings/power_series_mpoly.cpython-314t-aarch64-linux-musl.so +0 -0
  601. sage/rings/power_series_mpoly.pxd +9 -0
  602. sage/rings/power_series_mpoly.pyx +161 -0
  603. sage/rings/power_series_poly.cpython-314t-aarch64-linux-musl.so +0 -0
  604. sage/rings/power_series_poly.pxd +10 -0
  605. sage/rings/power_series_poly.pyx +1317 -0
  606. sage/rings/power_series_ring.py +1441 -0
  607. sage/rings/power_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
  608. sage/rings/power_series_ring_element.pxd +12 -0
  609. sage/rings/power_series_ring_element.pyx +3028 -0
  610. sage/rings/puiseux_series_ring.py +487 -0
  611. sage/rings/puiseux_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
  612. sage/rings/puiseux_series_ring_element.pxd +7 -0
  613. sage/rings/puiseux_series_ring_element.pyx +1055 -0
  614. sage/rings/qqbar_decorators.py +167 -0
  615. sage/rings/quotient_ring.py +1598 -0
  616. sage/rings/quotient_ring_element.py +979 -0
  617. sage/rings/rational.cpython-314t-aarch64-linux-musl.so +0 -0
  618. sage/rings/rational.pxd +20 -0
  619. sage/rings/rational.pyx +4284 -0
  620. sage/rings/rational_field.py +1730 -0
  621. sage/rings/real_double.cpython-314t-aarch64-linux-musl.so +0 -0
  622. sage/rings/real_double.pxd +16 -0
  623. sage/rings/real_double.pyx +2218 -0
  624. sage/rings/real_lazy.cpython-314t-aarch64-linux-musl.so +0 -0
  625. sage/rings/real_lazy.pxd +30 -0
  626. sage/rings/real_lazy.pyx +1773 -0
  627. sage/rings/ring.cpython-314t-aarch64-linux-musl.so +0 -0
  628. sage/rings/ring.pxd +30 -0
  629. sage/rings/ring.pyx +850 -0
  630. sage/rings/semirings/all.py +3 -0
  631. sage/rings/semirings/non_negative_integer_semiring.py +107 -0
  632. sage/rings/semirings/tropical_mpolynomial.py +972 -0
  633. sage/rings/semirings/tropical_polynomial.py +997 -0
  634. sage/rings/semirings/tropical_semiring.cpython-314t-aarch64-linux-musl.so +0 -0
  635. sage/rings/semirings/tropical_semiring.pyx +676 -0
  636. sage/rings/semirings/tropical_variety.py +1701 -0
  637. sage/rings/sum_of_squares.cpython-314t-aarch64-linux-musl.so +0 -0
  638. sage/rings/sum_of_squares.pxd +3 -0
  639. sage/rings/sum_of_squares.pyx +336 -0
  640. sage/rings/tests.py +504 -0
  641. sage/schemes/affine/affine_homset.py +508 -0
  642. sage/schemes/affine/affine_morphism.py +1574 -0
  643. sage/schemes/affine/affine_point.py +460 -0
  644. sage/schemes/affine/affine_rational_point.py +308 -0
  645. sage/schemes/affine/affine_space.py +1264 -0
  646. sage/schemes/affine/affine_subscheme.py +592 -0
  647. sage/schemes/affine/all.py +25 -0
  648. sage/schemes/all__sagemath_categories.py +5 -0
  649. sage/schemes/generic/algebraic_scheme.py +2092 -0
  650. sage/schemes/generic/all.py +5 -0
  651. sage/schemes/generic/ambient_space.py +400 -0
  652. sage/schemes/generic/divisor.py +465 -0
  653. sage/schemes/generic/divisor_group.py +313 -0
  654. sage/schemes/generic/glue.py +84 -0
  655. sage/schemes/generic/homset.py +820 -0
  656. sage/schemes/generic/hypersurface.py +234 -0
  657. sage/schemes/generic/morphism.py +2107 -0
  658. sage/schemes/generic/point.py +237 -0
  659. sage/schemes/generic/scheme.py +1190 -0
  660. sage/schemes/generic/spec.py +199 -0
  661. sage/schemes/product_projective/all.py +6 -0
  662. sage/schemes/product_projective/homset.py +236 -0
  663. sage/schemes/product_projective/morphism.py +517 -0
  664. sage/schemes/product_projective/point.py +568 -0
  665. sage/schemes/product_projective/rational_point.py +550 -0
  666. sage/schemes/product_projective/space.py +1301 -0
  667. sage/schemes/product_projective/subscheme.py +466 -0
  668. sage/schemes/projective/all.py +24 -0
  669. sage/schemes/projective/proj_bdd_height.py +453 -0
  670. sage/schemes/projective/projective_homset.py +718 -0
  671. sage/schemes/projective/projective_morphism.py +2792 -0
  672. sage/schemes/projective/projective_point.py +1484 -0
  673. sage/schemes/projective/projective_rational_point.py +569 -0
  674. sage/schemes/projective/projective_space.py +2571 -0
  675. sage/schemes/projective/projective_subscheme.py +1574 -0
  676. sage/sets/all.py +17 -0
  677. sage/sets/cartesian_product.py +376 -0
  678. sage/sets/condition_set.py +525 -0
  679. sage/sets/disjoint_set.cpython-314t-aarch64-linux-musl.so +0 -0
  680. sage/sets/disjoint_set.pxd +36 -0
  681. sage/sets/disjoint_set.pyx +998 -0
  682. sage/sets/disjoint_union_enumerated_sets.py +625 -0
  683. sage/sets/family.cpython-314t-aarch64-linux-musl.so +0 -0
  684. sage/sets/family.pxd +12 -0
  685. sage/sets/family.pyx +1556 -0
  686. sage/sets/finite_enumerated_set.py +406 -0
  687. sage/sets/finite_set_map_cy.cpython-314t-aarch64-linux-musl.so +0 -0
  688. sage/sets/finite_set_map_cy.pxd +34 -0
  689. sage/sets/finite_set_map_cy.pyx +708 -0
  690. sage/sets/finite_set_maps.py +591 -0
  691. sage/sets/image_set.py +448 -0
  692. sage/sets/integer_range.py +829 -0
  693. sage/sets/non_negative_integers.py +241 -0
  694. sage/sets/positive_integers.py +93 -0
  695. sage/sets/primes.py +188 -0
  696. sage/sets/real_set.py +2760 -0
  697. sage/sets/recursively_enumerated_set.cpython-314t-aarch64-linux-musl.so +0 -0
  698. sage/sets/recursively_enumerated_set.pxd +31 -0
  699. sage/sets/recursively_enumerated_set.pyx +2082 -0
  700. sage/sets/set.py +2083 -0
  701. sage/sets/set_from_iterator.py +1021 -0
  702. sage/sets/totally_ordered_finite_set.py +329 -0
  703. sage/symbolic/all__sagemath_categories.py +1 -0
  704. sage/symbolic/function.cpython-314t-aarch64-linux-musl.so +0 -0
  705. sage/symbolic/function.pxd +29 -0
  706. sage/symbolic/function.pyx +1488 -0
  707. sage/symbolic/symbols.py +56 -0
  708. sage/tests/all__sagemath_categories.py +1 -0
  709. sage/tests/cython.cpython-314t-aarch64-linux-musl.so +0 -0
  710. sage/tests/cython.pyx +37 -0
  711. sage/tests/stl_vector.cpython-314t-aarch64-linux-musl.so +0 -0
  712. sage/tests/stl_vector.pyx +171 -0
  713. sage/typeset/all.py +6 -0
  714. sage/typeset/ascii_art.py +295 -0
  715. sage/typeset/character_art.py +789 -0
  716. sage/typeset/character_art_factory.py +572 -0
  717. sage/typeset/symbols.py +334 -0
  718. sage/typeset/unicode_art.py +183 -0
  719. sage/typeset/unicode_characters.py +101 -0
@@ -0,0 +1,1893 @@
1
+ # sage_setup: distribution = sagemath-categories
2
+ # sage.doctest: needs sage.geometry.polyhedron
3
+ r"""
4
+ Generic Backend for LP solvers
5
+
6
+ This class only lists the methods that should be defined by any
7
+ interface with a LP Solver. All these methods immediately raise
8
+ :exc:`NotImplementedError` exceptions when called, and are obviously
9
+ meant to be replaced by the solver-specific method. This file can also
10
+ be used as a template to create a new interface : one would only need
11
+ to replace the occurrences of ``"Nonexistent_LP_solver"`` by the
12
+ solver's name, and replace ``GenericBackend`` by
13
+ ``SolverName(GenericBackend)`` so that the new solver extends this
14
+ class.
15
+
16
+ AUTHORS:
17
+
18
+ - Nathann Cohen (2010-10) : initial implementation
19
+ - Risan (2012-02) : extension for PPL backend
20
+ - Ingolfur Edvardsson (2014-06): extension for CVXOPT backend
21
+ """
22
+
23
+ #*****************************************************************************
24
+ # Copyright (C) 2010 Nathann Cohen <nathann.cohen@gmail.com>
25
+ #
26
+ # This program is free software: you can redistribute it and/or modify
27
+ # it under the terms of the GNU General Public License as published by
28
+ # the Free Software Foundation, either version 2 of the License, or
29
+ # (at your option) any later version.
30
+ # http://www.gnu.org/licenses/
31
+ #*****************************************************************************
32
+
33
+ from copy import copy
34
+
35
+ cdef class GenericBackend:
36
+
37
+ cpdef base_ring(self):
38
+ from sage.rings.real_double import RDF
39
+ return RDF
40
+
41
+ cpdef zero(self):
42
+ return self.base_ring()(0)
43
+
44
+ cpdef int add_variable(self, lower_bound=0, upper_bound=None,
45
+ binary=False, continuous=True, integer=False,
46
+ obj=None, name=None) except -1:
47
+ """
48
+ Add a variable.
49
+
50
+ This amounts to adding a new column to the matrix. By default,
51
+ the variable is both positive and real.
52
+
53
+ INPUT:
54
+
55
+ - ``lower_bound`` -- the lower bound of the variable (default: 0)
56
+
57
+ - ``upper_bound`` -- the upper bound of the variable (default: ``None``)
58
+
59
+ - ``binary`` -- ``True`` if the variable is binary (default: ``False``)
60
+
61
+ - ``continuous`` -- ``True`` if the variable is continuous (default: ``True``)
62
+
63
+ - ``integer`` -- ``True`` if the variable is integral (default: ``False``)
64
+
65
+ - ``obj`` -- (optional) coefficient of this variable in the objective function (default: 0.0)
66
+
67
+ - ``name`` -- an optional name for the newly added variable (default: ``None``)
68
+
69
+ OUTPUT: the index of the newly created variable
70
+
71
+ EXAMPLES::
72
+
73
+ sage: # optional - nonexistent_lp_solver
74
+ sage: from sage.numerical.backends.generic_backend import get_solver
75
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
76
+ sage: p.ncols()
77
+ 0
78
+ sage: p.add_variable()
79
+ 0
80
+ sage: p.ncols()
81
+ 1
82
+ sage: p.add_variable(binary=True)
83
+ 1
84
+ sage: p.add_variable(lower_bound=-2.0, integer=True)
85
+ 2
86
+ sage: p.add_variable(continuous=True, integer=True)
87
+ Traceback (most recent call last):
88
+ ...
89
+ ValueError: ...
90
+ sage: p.add_variable(name='x', obj=1.0)
91
+ 3
92
+ sage: p.col_name(3)
93
+ 'x'
94
+ sage: p.objective_coefficient(3)
95
+ 1.0
96
+ """
97
+ raise NotImplementedError()
98
+
99
+ cpdef int add_variables(self, int n, lower_bound=False, upper_bound=None, binary=False, continuous=True, integer=False, obj=None, names=None) except -1:
100
+ """
101
+ Add ``n`` variables.
102
+
103
+ This amounts to adding new columns to the matrix. By default,
104
+ the variables are both nonnegative and real.
105
+
106
+ INPUT:
107
+
108
+ - ``n`` -- the number of new variables (must be > 0)
109
+
110
+ - ``lower_bound`` -- the lower bound of the variable (default: 0)
111
+
112
+ - ``upper_bound`` -- the upper bound of the variable (default: ``None``)
113
+
114
+ - ``binary`` -- ``True`` if the variable is binary (default: ``False``)
115
+
116
+ - ``continuous`` -- ``True`` if the variable is binary (default: ``True``)
117
+
118
+ - ``integer`` -- ``True`` if the variable is binary (default: ``False``)
119
+
120
+ - ``obj`` -- coefficient of all variables in the objective function (default: 0.0)
121
+
122
+ - ``names`` -- list of names (default: ``None``)
123
+
124
+ OUTPUT: the index of the variable created last
125
+
126
+ EXAMPLES::
127
+
128
+ sage: # optional - nonexistent_lp_solver
129
+ sage: from sage.numerical.backends.generic_backend import get_solver
130
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
131
+ sage: p.ncols()
132
+ 0
133
+ sage: p.add_variables(5)
134
+ 4
135
+ sage: p.ncols()
136
+ 5
137
+ sage: p.add_variables(2, lower_bound=-2.0, integer=True, names=['a','b'])
138
+ 6
139
+
140
+ TESTS:
141
+
142
+ Check that arguments are used::
143
+
144
+ sage: # optional - nonexistent_lp_solver
145
+ sage: p.col_bounds(5) # tol 1e-8
146
+ (-2.0, None)
147
+ sage: p.is_variable_integer(5)
148
+ True
149
+ sage: p.col_name(5)
150
+ 'a'
151
+ sage: p.objective_coefficient(5) # tol 1e-8
152
+ 42.0
153
+ """
154
+ cdef int i
155
+ cdef int value
156
+ if lower_bound is False:
157
+ lower_bound = self.zero()
158
+ if obj is None:
159
+ obj = self.zero()
160
+ for i in range(n):
161
+ value = self.add_variable(lower_bound=lower_bound,
162
+ upper_bound=upper_bound,
163
+ binary=binary,
164
+ continuous=continuous,
165
+ integer=integer,
166
+ obj=obj,
167
+ name=None if names is None else names[i])
168
+ return value
169
+
170
+ @classmethod
171
+ def _test_add_variables(cls, tester=None, **options):
172
+ """
173
+ Run tests on the method :meth:`add_linear_constraints`.
174
+
175
+ TESTS::
176
+
177
+ sage: from sage.numerical.backends.generic_backend import GenericBackend
178
+ sage: p = GenericBackend()
179
+ sage: p._test_add_variables()
180
+ Traceback (most recent call last):
181
+ ...
182
+ NotImplementedError
183
+
184
+ Flush any stray output -- see :issue:`28622`::
185
+
186
+ sage: sys.stdout.flush()
187
+ ...
188
+ """
189
+ p = cls() # fresh instance of the backend
190
+ if tester is None:
191
+ tester = p._tester(**options)
192
+ # Test from CVXOPT interface:
193
+ ncols_added = 5
194
+ ncols_before = p.ncols()
195
+ add_variables_result = p.add_variables(ncols_added)
196
+ ncols_after = p.ncols()
197
+ tester.assertEqual(ncols_after, ncols_before+ncols_added, "Added the wrong number of columns")
198
+ # Test from CVXOPT interface, continued; edited to support InteractiveLPBackend
199
+ ncols_before = p.ncols()
200
+ try:
201
+ col_bounds = (-2.0, None)
202
+ add_variables_result = p.add_variables(2, lower_bound=col_bounds[0], upper_bound=col_bounds[1],
203
+ obj=42.0, names=['a','b'])
204
+ except NotImplementedError:
205
+ # The InteractiveLPBackend does not allow general variable bounds.
206
+ col_bounds = (0.0, None)
207
+ add_variables_result = p.add_variables(2, lower_bound=col_bounds[0], upper_bound=col_bounds[1],
208
+ obj=42.0, names=['a','b'])
209
+ ncols_after = p.ncols()
210
+ tester.assertAlmostEqual(p.col_bounds(ncols_before), col_bounds)
211
+ tester.assertEqual(p.col_name(ncols_before), 'a')
212
+ tester.assertAlmostEqual(p.objective_coefficient(ncols_before), 42.0)
213
+
214
+ cpdef set_variable_type(self, int variable, int vtype):
215
+ """
216
+ Set the type of a variable.
217
+
218
+ INPUT:
219
+
220
+ - ``variable`` -- integer; the variable's id
221
+
222
+ - ``vtype`` -- integer:
223
+
224
+ * `1` Integer
225
+ * `0` Binary
226
+ * `-1` Continuous
227
+
228
+ EXAMPLES::
229
+
230
+ sage: # optional - nonexistent_lp_solver
231
+ sage: from sage.numerical.backends.generic_backend import get_solver
232
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
233
+ sage: p.ncols()
234
+ 0
235
+ sage: p.add_variable()
236
+ 0
237
+ sage: p.set_variable_type(0,1)
238
+ sage: p.is_variable_integer(0)
239
+ True
240
+ """
241
+ raise NotImplementedError()
242
+
243
+ cpdef set_sense(self, int sense):
244
+ """
245
+ Set the direction (maximization/minimization).
246
+
247
+ INPUT:
248
+
249
+ - ``sense`` -- integer:
250
+
251
+ * +1 => Maximization
252
+ * -1 => Minimization
253
+
254
+ EXAMPLES::
255
+
256
+ sage: # optional - nonexistent_lp_solver
257
+ sage: from sage.numerical.backends.generic_backend import get_solver
258
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
259
+ sage: p.is_maximization()
260
+ True
261
+ sage: p.set_sense(-1)
262
+ sage: p.is_maximization()
263
+ False
264
+ """
265
+ raise NotImplementedError()
266
+
267
+ @classmethod
268
+ def _test_sense(cls, tester=None, **options):
269
+ """
270
+ Run tests on ``set_sense`` and ``is_maximization``.
271
+
272
+ TESTS::
273
+
274
+ sage: from sage.numerical.backends.generic_backend import GenericBackend
275
+ sage: p = GenericBackend()
276
+ sage: p._test_sense() # optional - Nonexistent_LP_solver
277
+ Exception NotImplementedError ...
278
+ """
279
+ p = cls() # fresh instance of the backend
280
+ if tester is None:
281
+ tester = p._tester(**options)
282
+ tester.assertEqual(p.is_maximization(), True)
283
+ tester.assertIsNone(p.set_sense(-1))
284
+ tester.assertEqual(p.is_maximization(), False)
285
+ tester.assertIsNone(p.set_sense(1))
286
+ tester.assertEqual(p.is_maximization(), True)
287
+
288
+ cpdef objective_coefficient(self, int variable, coeff=None):
289
+ """
290
+ Set or get the coefficient of a variable in the objective
291
+ function
292
+
293
+ INPUT:
294
+
295
+ - ``variable`` -- integer; the variable's id
296
+
297
+ - ``coeff`` -- double; its coefficient
298
+
299
+ EXAMPLES::
300
+
301
+ sage: # optional - nonexistent_lp_solver
302
+ sage: from sage.numerical.backends.generic_backend import get_solver
303
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
304
+ sage: p.add_variable()
305
+ 0
306
+ sage: p.objective_coefficient(0)
307
+ 0.0
308
+ sage: p.objective_coefficient(0,2)
309
+ sage: p.objective_coefficient(0)
310
+ 2.0
311
+ """
312
+ raise NotImplementedError()
313
+
314
+ cpdef objective_constant_term(self, d=None):
315
+ """
316
+ Set or get the constant term in the objective function.
317
+
318
+ INPUT:
319
+
320
+ - ``d`` -- double; its coefficient. If ``None`` (default), return the
321
+ current value.
322
+
323
+ EXAMPLES::
324
+
325
+ sage: # optional - nonexistent_lp_solver
326
+ sage: from sage.numerical.backends.generic_backend import get_solver
327
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
328
+ sage: p.objective_constant_term()
329
+ 0.0
330
+ sage: p.objective_constant_term(42)
331
+ sage: p.objective_constant_term()
332
+ 42.0
333
+ """
334
+ if d is None:
335
+ return self.obj_constant_term
336
+ else:
337
+ self.obj_constant_term = d
338
+
339
+ cpdef set_objective(self, list coeff, d=0.0):
340
+ """
341
+ Set the objective function.
342
+
343
+ INPUT:
344
+
345
+ - ``coeff`` -- list of real values, whose i-th element is the
346
+ coefficient of the i-th variable in the objective function
347
+
348
+ - ``d`` -- double; the constant term in the linear function (set to `0`
349
+ by default)
350
+
351
+ EXAMPLES::
352
+
353
+ sage: # optional - nonexistent_lp_solver
354
+ sage: from sage.numerical.backends.generic_backend import get_solver
355
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
356
+ sage: p.add_variables(5)
357
+ 4
358
+ sage: p.set_objective([1, 1, 2, 1, 3])
359
+ sage: [p.objective_coefficient(x) for x in range(5)]
360
+ [1.0, 1.0, 2.0, 1.0, 3.0]
361
+
362
+ Constants in the objective function are respected::
363
+
364
+ sage: # optional - nonexistent_lp_solver
365
+ sage: p = MixedIntegerLinearProgram(solver='Nonexistent_LP_solver')
366
+ sage: x,y = p[0], p[1]
367
+ sage: p.add_constraint(2*x + 3*y, max=6)
368
+ sage: p.add_constraint(3*x + 2*y, max=6)
369
+ sage: p.set_objective(x + y + 7)
370
+ sage: p.set_integer(x); p.set_integer(y)
371
+ sage: p.solve()
372
+ 9.0
373
+ """
374
+ raise NotImplementedError()
375
+
376
+ cpdef set_verbosity(self, int level):
377
+ """
378
+ Set the log (verbosity) level.
379
+
380
+ INPUT:
381
+
382
+ - ``level`` -- integer; from 0 (no verbosity) to 3
383
+
384
+ EXAMPLES::
385
+
386
+ sage: from sage.numerical.backends.generic_backend import get_solver
387
+ sage: p = get_solver(solver="Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
388
+ sage: p.set_verbosity(2) # optional - Nonexistent_LP_solver
389
+ """
390
+ raise NotImplementedError()
391
+
392
+ cpdef remove_constraint(self, int i):
393
+ r"""
394
+ Remove a constraint.
395
+
396
+ INPUT:
397
+
398
+ - ``i`` -- index of the constraint to remove
399
+
400
+ EXAMPLES::
401
+
402
+ sage: # optional - nonexistent_lp_solver
403
+ sage: p = MixedIntegerLinearProgram(solver="Nonexistent_LP_solver")
404
+ sage: v = p.new_variable(nonnegative=True)
405
+ sage: x,y = v[0], v[1]
406
+ sage: p.add_constraint(2*x + 3*y, max=6)
407
+ sage: p.add_constraint(3*x + 2*y, max=6)
408
+ sage: p.set_objective(x + y + 7)
409
+ sage: p.set_integer(x); p.set_integer(y)
410
+ sage: p.solve()
411
+ 9.0
412
+ sage: p.remove_constraint(0)
413
+ sage: p.solve()
414
+ 10.0
415
+ sage: p.get_values([x,y])
416
+ [0.0, 3.0]
417
+ """
418
+ raise NotImplementedError()
419
+
420
+ cpdef remove_constraints(self, constraints):
421
+ r"""
422
+ Remove several constraints.
423
+
424
+ INPUT:
425
+
426
+ - ``constraints`` -- an iterable containing the indices of the rows to remove
427
+
428
+ EXAMPLES::
429
+
430
+ sage: # optional - nonexistent_lp_solver
431
+ sage: from sage.numerical.backends.generic_backend import get_solver
432
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
433
+ sage: p.add_variables(2)
434
+ 1
435
+ sage: p.add_linear_constraint([(0, 2), (1, 3)], None, 6)
436
+ sage: p.add_linear_constraint([(0, 3), (1, 2)], None, 6)
437
+ sage: p.remove_constraints([0, 1])
438
+ """
439
+ if isinstance(constraints, int):
440
+ self.remove_constraint(constraints)
441
+ return
442
+
443
+ cdef int last = self.nrows() + 1
444
+
445
+ for c in sorted(constraints, reverse=True):
446
+ if c != last:
447
+ self.remove_constraint(c)
448
+ last = c
449
+
450
+ cpdef add_linear_constraint(self, coefficients, lower_bound, upper_bound, name=None):
451
+ """
452
+ Add a linear constraint.
453
+
454
+ INPUT:
455
+
456
+ - ``coefficients`` -- an iterable of pairs ``(i, v)``. In each
457
+ pair, ``i`` is a variable index (integer) and ``v`` is a
458
+ value (element of :meth:`base_ring`).
459
+
460
+ - ``lower_bound`` -- element of :meth:`base_ring` or
461
+ ``None``; the lower bound
462
+
463
+ - ``upper_bound`` -- element of :meth:`base_ring` or
464
+ ``None``; the upper bound
465
+
466
+ - ``name`` -- string or ``None``; optional name for this row
467
+
468
+ EXAMPLES::
469
+
470
+ sage: # optional - nonexistent_lp_solver
471
+ sage: from sage.numerical.backends.generic_backend import get_solver
472
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
473
+ sage: p.add_variables(5)
474
+ 4
475
+ sage: p.add_linear_constraint( zip(range(5), range(5)), 2.0, 2.0)
476
+ sage: p.row(0)
477
+ ([0, 1, 2, 3, 4], [0.0, 1.0, 2.0, 3.0, 4.0])
478
+ sage: p.row_bounds(0)
479
+ (2.0, 2.0)
480
+ sage: p.add_linear_constraint( zip(range(5), range(5)), 1.0, 1.0, name='foo')
481
+ sage: p.row_name(1)
482
+ 'foo'
483
+ """
484
+ raise NotImplementedError('add_linear_constraint')
485
+
486
+ cpdef add_linear_constraint_vector(self, degree, coefficients, lower_bound, upper_bound, name=None):
487
+ """
488
+ Add a vector-valued linear constraint.
489
+
490
+ .. NOTE::
491
+
492
+ This is the generic implementation, which will split the
493
+ vector-valued constraint into components and add these
494
+ individually. Backends are encouraged to replace it with
495
+ their own optimized implementation.
496
+
497
+ INPUT:
498
+
499
+ - ``degree`` -- integer; the vector degree, that is, the
500
+ number of new scalar constraints
501
+
502
+ - ``coefficients`` -- an iterable of pairs ``(i, v)``. In each
503
+ pair, ``i`` is a variable index (integer) and ``v`` is a
504
+ vector (real and of length ``degree``).
505
+
506
+ - ``lower_bound`` -- either a vector or ``None``; the
507
+ component-wise lower bound
508
+
509
+ - ``upper_bound`` -- either a vector or ``None``; the
510
+ component-wise upper bound
511
+
512
+ - ``name`` -- string or ``None``; an optional name for all new
513
+ rows
514
+
515
+ EXAMPLES::
516
+
517
+ sage: # optional - nonexistent_lp_solver
518
+ sage: from sage.numerical.backends.generic_backend import get_solver
519
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
520
+ sage: coeffs = ([0, vector([1, 2])], [1, vector([2, 3])])
521
+ sage: upper = vector([5, 5])
522
+ sage: lower = vector([0, 0])
523
+ sage: p.add_variables(2)
524
+ 1
525
+ sage: p.add_linear_constraint_vector(2, coeffs, lower, upper, 'foo')
526
+ """
527
+ for d in range(degree):
528
+ coefficients_d = []
529
+ for i, c in coefficients:
530
+ coefficients_d.append((i, c[d]))
531
+ lower_bound_d = None if lower_bound is None else lower_bound[d]
532
+ upper_bound_d = None if upper_bound is None else upper_bound[d]
533
+ self.add_linear_constraint(coefficients_d, lower_bound_d, upper_bound_d, name=name)
534
+
535
+ @classmethod
536
+ def _test_add_linear_constraint_vector(cls, tester=None, **options):
537
+ """
538
+ Run tests on the method :meth:`add_linear_constraint_vector`.
539
+
540
+ TESTS::
541
+
542
+ sage: from sage.numerical.backends.generic_backend import GenericBackend
543
+ sage: p = GenericBackend()
544
+ sage: p._test_add_linear_constraint_vector()
545
+ Traceback (most recent call last):
546
+ ...
547
+ NotImplementedError
548
+ """
549
+ p = cls() # fresh instance of the backend
550
+ if tester is None:
551
+ tester = p._tester(**options)
552
+ from sage.modules.free_module_element import vector
553
+ # Ensure there are at least 2 variables
554
+ p.add_variables(2)
555
+ coeffs = ([0, vector([1, 2])], [1, vector([2, 3])])
556
+ upper = vector([5, 5])
557
+ lower = vector([0, 0])
558
+ try:
559
+ p.add_linear_constraint_vector(2, coeffs, lower, upper, 'foo')
560
+ except NotImplementedError:
561
+ # Ranged constraints are not supported by InteractiveLPBackend
562
+ lower = None
563
+ p.add_linear_constraint_vector(2, coeffs, lower, upper, 'foo')
564
+ # FIXME: Tests here. Careful what we expect regarding ranged constraints with some solvers.
565
+
566
+ cpdef add_col(self, indices, coeffs):
567
+ """
568
+ Add a column.
569
+
570
+ INPUT:
571
+
572
+ - ``indices`` -- list of integers; this list contains the
573
+ indices of the constraints in which the variable's
574
+ coefficient is nonzero
575
+
576
+ - ``coeffs`` -- list of real values; associates a coefficient
577
+ to the variable in each of the constraints in which it
578
+ appears. Namely, the i-th entry of ``coeffs`` corresponds to
579
+ the coefficient of the variable in the constraint
580
+ represented by the i-th entry in ``indices``.
581
+
582
+ .. NOTE::
583
+
584
+ ``indices`` and ``coeffs`` are expected to be of the same
585
+ length.
586
+
587
+ EXAMPLES::
588
+
589
+ sage: # optional - nonexistent_lp_solver
590
+ sage: from sage.numerical.backends.generic_backend import get_solver
591
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
592
+ sage: p.ncols()
593
+ 0
594
+ sage: p.nrows()
595
+ 0
596
+ sage: p.add_linear_constraints(5, 0, None)
597
+ sage: p.add_col(list(range(5)), list(range(5)))
598
+ sage: p.nrows()
599
+ 5
600
+ """
601
+ raise NotImplementedError()
602
+
603
+ @classmethod
604
+ def _test_add_col(cls, tester=None, **options):
605
+ """
606
+ Run tests on the method :meth:`add_col`.
607
+
608
+ TESTS::
609
+
610
+ sage: from sage.numerical.backends.generic_backend import GenericBackend
611
+ sage: p = GenericBackend()
612
+ sage: p._test_add_col()
613
+ Traceback (most recent call last):
614
+ ...
615
+ NotImplementedError: ...
616
+ """
617
+ p = cls() # fresh instance of the backend
618
+ if tester is None:
619
+ tester = p._tester(**options)
620
+ tester.assertIsNone(p.add_linear_constraints(5, 0, None))
621
+ tester.assertIsNone(p.add_col([0, 1, 2, 3, 4], [0, 1, 2, 3, 4]))
622
+ tester.assertEqual(p.nrows(), 5)
623
+ for 1 <= i <= 4:
624
+ tester.assertEqual(p.row(i), ([0], [i]))
625
+
626
+ cpdef add_linear_constraints(self, int number, lower_bound, upper_bound, names=None):
627
+ """
628
+ Add ``'number`` linear constraints.
629
+
630
+ INPUT:
631
+
632
+ - ``number`` -- integer; the number of constraints to add
633
+
634
+ - ``lower_bound`` -- a lower bound, either a real value or ``None``
635
+
636
+ - ``upper_bound`` -- an upper bound, either a real value or ``None``
637
+
638
+ - ``names`` -- an optional list of names (default: ``None``)
639
+
640
+ EXAMPLES::
641
+
642
+ sage: # optional - nonexistent_lp_solver
643
+ sage: from sage.numerical.backends.generic_backend import get_solver
644
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
645
+ sage: p.add_variables(5)
646
+ 5
647
+ sage: p.add_linear_constraints(5, None, 2)
648
+ sage: p.row(4)
649
+ ([], [])
650
+ sage: p.row_bounds(4)
651
+ (None, 2.0)
652
+ """
653
+ cdef int i
654
+ for 0<= i<number:
655
+ self.add_linear_constraint([],lower_bound, upper_bound, name = (names[i] if names else None))
656
+
657
+ @classmethod
658
+ def _test_add_linear_constraints(cls, tester=None, **options):
659
+ """
660
+ Run tests on the method :meth:`add_linear_constraints`.
661
+
662
+ TESTS::
663
+
664
+ sage: from sage.numerical.backends.generic_backend import GenericBackend
665
+ sage: p = GenericBackend()
666
+ sage: p._test_add_linear_constraints()
667
+ Traceback (most recent call last):
668
+ ...
669
+ NotImplementedError...
670
+
671
+ Flush any stray output -- see :issue:`28622`::
672
+
673
+ sage: sys.stdout.flush()
674
+ ...
675
+ """
676
+ p = cls() # fresh instance of the backend
677
+ if tester is None:
678
+ tester = p._tester(**options)
679
+ nrows_before = p.nrows()
680
+ nrows_added = 5
681
+ p.add_linear_constraints(nrows_added, None, 2)
682
+ nrows_after = p.nrows()
683
+ # Test correct number of rows
684
+ tester.assertEqual(nrows_after, nrows_before+nrows_added, "Added the wrong number of rows")
685
+ # Test contents of the new rows are correct (sparse zero)
686
+ for i in range(nrows_before, nrows_after):
687
+ tester.assertEqual(p.row(i), ([], []))
688
+ tester.assertEqual(p.row_bounds(i), (None, 2.0))
689
+ # Test from COINBackend.add_linear_constraints:
690
+ tester.assertIsNone(p.add_linear_constraints(2, None, 2, names=['foo', 'bar']))
691
+ tester.assertEqual(p.row_name(6), 'bar')
692
+ # Test that it did not add mysterious new variables:
693
+ tester.assertEqual(p.ncols(), 0)
694
+
695
+ cpdef int solve(self) except -1:
696
+ """
697
+ Solve the problem.
698
+
699
+ .. NOTE::
700
+
701
+ This method raises ``MIPSolverException`` exceptions when
702
+ the solution cannot be computed for any reason (none
703
+ exists, or the LP solver was not able to find it, etc...)
704
+
705
+ EXAMPLES::
706
+
707
+ sage: # optional - nonexistent_lp_solver
708
+ sage: from sage.numerical.backends.generic_backend import get_solver
709
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
710
+ sage: p.add_linear_constraints(5, 0, None)
711
+ sage: p.add_col(list(range(5)), list(range(5)))
712
+ sage: p.solve()
713
+ 0
714
+ sage: p.objective_coefficient(0,1)
715
+ sage: p.solve()
716
+ Traceback (most recent call last):
717
+ ...
718
+ MIPSolverException: ...
719
+ """
720
+ raise NotImplementedError()
721
+
722
+ ## Any test methods involving calls to 'solve' are set up as class methods,
723
+ ## which make a fresh instance of the backend.
724
+ @classmethod
725
+ def _test_solve(cls, tester=None, **options):
726
+ """
727
+ Trivial test for the solve method.
728
+
729
+ TESTS::
730
+
731
+ sage: from sage.numerical.backends.generic_backend import GenericBackend
732
+ sage: p = GenericBackend()
733
+ sage: p._test_solve()
734
+ Traceback (most recent call last):
735
+ ...
736
+ NotImplementedError: ...
737
+ """
738
+ p = cls() # fresh instance of the backend
739
+ if tester is None:
740
+ tester = p._tester(**options)
741
+ # From doctest of GenericBackend.solve:
742
+ tester.assertIsNone(p.add_linear_constraints(5, 0, None))
743
+ tester.assertIsNone(p.add_col(list(range(5)), list(range(5))))
744
+ tester.assertEqual(p.solve(), 0)
745
+ tester.assertIsNone(p.objective_coefficient(0,1))
746
+ from sage.numerical.mip import MIPSolverException
747
+ #with tester.assertRaisesRegexp(MIPSolverException, "unbounded") as cm: ## --- too specific
748
+ with tester.assertRaises(MIPSolverException) as cm: # unbounded
749
+ p.solve()
750
+
751
+ cpdef get_objective_value(self):
752
+ """
753
+ Return the value of the objective function.
754
+
755
+ .. NOTE::
756
+
757
+ Behavior is undefined unless ``solve`` has been called before.
758
+
759
+ EXAMPLES::
760
+
761
+ sage: # optional - nonexistent_lp_solver
762
+ sage: from sage.numerical.backends.generic_backend import get_solver
763
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
764
+ sage: p.add_variables(2)
765
+ 1
766
+ sage: p.add_linear_constraint([(0,1), (1,2)], None, 3)
767
+ sage: p.set_objective([2, 5])
768
+ sage: p.solve()
769
+ 0
770
+ sage: p.get_objective_value()
771
+ 7.5
772
+ sage: p.get_variable_value(0)
773
+ 0.0
774
+ sage: p.get_variable_value(1)
775
+ 1.5
776
+ """
777
+
778
+ raise NotImplementedError()
779
+
780
+ cpdef best_known_objective_bound(self):
781
+ r"""
782
+ Return the value of the currently best known bound.
783
+
784
+ This method returns the current best upper (resp. lower) bound on the
785
+ optimal value of the objective function in a maximization
786
+ (resp. minimization) problem. It is equal to the output of
787
+ :meth:`get_objective_value` if the MILP found an optimal solution, but
788
+ it can differ if it was interrupted manually or after a time limit (cf
789
+ :meth:`solver_parameter`).
790
+
791
+ .. NOTE::
792
+
793
+ Has no meaning unless ``solve`` has been called before.
794
+
795
+ EXAMPLES::
796
+
797
+ sage: # optional - nonexistent_lp_solver
798
+ sage: p = MixedIntegerLinearProgram(solver="Nonexistent_LP_solver")
799
+ sage: b = p.new_variable(binary=True)
800
+ sage: for u,v in graphs.CycleGraph(5).edges(labels=False):
801
+ ....: p.add_constraint(b[u]+b[v]<=1)
802
+ sage: p.set_objective(p.sum(b[x] for x in range(5)))
803
+ sage: p.solve()
804
+ 2.0
805
+ sage: pb = p.get_backend()
806
+ sage: pb.get_objective_value()
807
+ 2.0
808
+ sage: pb.best_known_objective_bound()
809
+ 2.0
810
+ """
811
+ raise NotImplementedError()
812
+
813
+ cpdef get_relative_objective_gap(self):
814
+ r"""
815
+ Return the relative objective gap of the best known solution.
816
+
817
+ For a minimization problem, this value is computed by
818
+ `(\texttt{bestinteger} - \texttt{bestobjective}) / (1e-10 +
819
+ |\texttt{bestobjective}|)`, where ``bestinteger`` is the value returned
820
+ by :meth:`~MixedIntegerLinearProgram.get_objective_value` and
821
+ ``bestobjective`` is the value returned by
822
+ :meth:`~MixedIntegerLinearProgram.best_known_objective_bound`. For a
823
+ maximization problem, the value is computed by `(\texttt{bestobjective}
824
+ - \texttt{bestinteger}) / (1e-10 + |\texttt{bestobjective}|)`.
825
+
826
+ .. NOTE::
827
+
828
+ Has no meaning unless ``solve`` has been called before.
829
+
830
+ EXAMPLES::
831
+
832
+ sage: # optional - nonexistent_lp_solver
833
+ sage: p = MixedIntegerLinearProgram(solver="Nonexistent_LP_solver")
834
+ sage: b = p.new_variable(binary=True)
835
+ sage: for u,v in graphs.CycleGraph(5).edges(labels=False):
836
+ ....: p.add_constraint(b[u]+b[v]<=1)
837
+ sage: p.set_objective(p.sum(b[x] for x in range(5)))
838
+ sage: p.solve()
839
+ 2.0
840
+ sage: pb = p.get_backend()
841
+ sage: pb.get_objective_value()
842
+ 2.0
843
+ sage: pb.get_relative_objective_gap()
844
+ 0.0
845
+ """
846
+ raise NotImplementedError()
847
+
848
+ cpdef get_variable_value(self, int variable):
849
+ """
850
+ Return the value of a variable given by the solver.
851
+
852
+ .. NOTE::
853
+
854
+ Behavior is undefined unless ``solve`` has been called before.
855
+
856
+ EXAMPLES::
857
+
858
+ sage: # optional - nonexistent_lp_solver
859
+ sage: from sage.numerical.backends.generic_backend import get_solver
860
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
861
+ sage: p.add_variables(2)
862
+ 1
863
+ sage: p.add_linear_constraint([(0,1), (1, 2)], None, 3)
864
+ sage: p.set_objective([2, 5])
865
+ sage: p.solve()
866
+ 0
867
+ sage: p.get_objective_value()
868
+ 7.5
869
+ sage: p.get_variable_value(0)
870
+ 0.0
871
+ sage: p.get_variable_value(1)
872
+ 1.5
873
+ """
874
+
875
+ raise NotImplementedError()
876
+
877
+ cpdef int ncols(self) noexcept:
878
+ """
879
+ Return the number of columns/variables.
880
+
881
+ EXAMPLES::
882
+
883
+ sage: # optional - nonexistent_lp_solver
884
+ sage: from sage.numerical.backends.generic_backend import get_solver
885
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
886
+ sage: p.ncols()
887
+ 0
888
+ sage: p.add_variables(2)
889
+ 1
890
+ sage: p.ncols()
891
+ 2
892
+ """
893
+
894
+ raise NotImplementedError()
895
+
896
+ def _test_ncols_nonnegative(self, **options):
897
+ # Issue #31103: This method has already been migrated to pytest (generic_backend_test)
898
+ # and should be removed as soon as the external sage_numerical_backends packages
899
+ # are updated to invoke pytest as part of their testsuite.
900
+ tester = self._tester(**options)
901
+ p = self
902
+ tester.assertGreaterEqual(self.ncols(), 0)
903
+
904
+ cpdef int nrows(self) noexcept:
905
+ """
906
+ Return the number of rows/constraints.
907
+
908
+ EXAMPLES::
909
+
910
+ sage: # optional - nonexistent_lp_solver
911
+ sage: from sage.numerical.backends.generic_backend import get_solver
912
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
913
+ sage: p.nrows()
914
+ 0
915
+ sage: p.add_linear_constraints(2, 2.0, None)
916
+ sage: p.nrows()
917
+ 2
918
+ """
919
+
920
+ raise NotImplementedError()
921
+
922
+ cpdef bint is_maximization(self) noexcept:
923
+ """
924
+ Test whether the problem is a maximization
925
+
926
+ EXAMPLES::
927
+
928
+ sage: # optional - nonexistent_lp_solver
929
+ sage: from sage.numerical.backends.generic_backend import get_solver
930
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
931
+ sage: p.is_maximization()
932
+ True
933
+ sage: p.set_sense(-1)
934
+ sage: p.is_maximization()
935
+ False
936
+ """
937
+ raise NotImplementedError()
938
+
939
+ cpdef problem_name(self, name=None):
940
+ """
941
+ Return or define the problem's name.
942
+
943
+ INPUT:
944
+
945
+ - ``name`` -- string; the problem's name. When set to
946
+ ``None`` (default), the method returns the problem's name.
947
+
948
+ EXAMPLES::
949
+
950
+ sage: from sage.numerical.backends.generic_backend import get_solver
951
+ sage: p = get_solver(solver="Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
952
+ sage: p.problem_name("There once was a french fry") # optional - Nonexistent_LP_solver
953
+ sage: print(p.problem_name()) # optional - Nonexistent_LP_solver
954
+ There once was a french fry
955
+ """
956
+
957
+ raise NotImplementedError()
958
+
959
+ cpdef write_lp(self, name):
960
+ """
961
+ Write the problem to a ``.lp`` file.
962
+
963
+ INPUT:
964
+
965
+ - ``filename`` -- string
966
+
967
+ EXAMPLES::
968
+
969
+ sage: # optional - nonexistent_lp_solver
970
+ sage: from sage.numerical.backends.generic_backend import get_solver
971
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
972
+ sage: p.add_variables(2)
973
+ 2
974
+ sage: p.add_linear_constraint([(0, 1], (1, 2)], None, 3)
975
+ sage: p.set_objective([2, 5])
976
+ sage: from tempfile import NamedTemporaryFile
977
+ sage: with NamedTemporaryFile(suffix='.lp') as f:
978
+ ....: p.write_lp(f.name)
979
+ """
980
+ raise NotImplementedError()
981
+
982
+ cpdef write_mps(self, name, int modern):
983
+ """
984
+ Write the problem to a ``.mps`` file.
985
+
986
+ INPUT:
987
+
988
+ - ``filename`` -- string
989
+
990
+ EXAMPLES::
991
+
992
+ sage: # optional - nonexistent_lp_solver
993
+ sage: from sage.numerical.backends.generic_backend import get_solver
994
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
995
+ sage: p.add_variables(2)
996
+ 2
997
+ sage: p.add_linear_constraint([(0, 1), (1, 2)], None, 3)
998
+ sage: p.set_objective([2, 5])
999
+ sage: from tempfile import NamedTemporaryFile
1000
+ sage: with NamedTemporaryFile(suffix='.lp') as f:
1001
+ ....: p.write_lp(f.name)
1002
+ """
1003
+ raise NotImplementedError()
1004
+
1005
+ cpdef copy(self):
1006
+ """
1007
+ Return a copy of ``self``.
1008
+
1009
+ EXAMPLES::
1010
+
1011
+ sage: # optional - nonexistent_lp_solver
1012
+ sage: from sage.numerical.backends.generic_backend import get_solver
1013
+ sage: p = MixedIntegerLinearProgram(solver="Nonexistent_LP_solver")
1014
+ sage: b = p.new_variable()
1015
+ sage: p.add_constraint(b[1] + b[2] <= 6)
1016
+ sage: p.set_objective(b[1] + b[2])
1017
+ sage: copy(p).solve()
1018
+ 6.0
1019
+ """
1020
+ return self.__copy__()
1021
+
1022
+ # Override this method in backends.
1023
+ cpdef __copy__(self):
1024
+ """
1025
+ Return a copy of ``self``.
1026
+
1027
+ EXAMPLES::
1028
+
1029
+ sage: # optional - nonexistent_lp_solver
1030
+ sage: from sage.numerical.backends.generic_backend import get_solver
1031
+ sage: p = MixedIntegerLinearProgram(solver="Nonexistent_LP_solver")
1032
+ sage: b = p.new_variable()
1033
+ sage: p.add_constraint(b[1] + b[2] <= 6)
1034
+ sage: p.set_objective(b[1] + b[2])
1035
+ sage: cp = copy(p.get_backend())
1036
+ sage: cp.solve()
1037
+ 0
1038
+ sage: cp.get_objective_value()
1039
+ 6.0
1040
+ """
1041
+ raise NotImplementedError()
1042
+
1043
+ def __deepcopy__(self, memo={}):
1044
+ """
1045
+ Return a deep copy of ``self``.
1046
+
1047
+ EXAMPLES::
1048
+
1049
+ sage: # optional - nonexistent_lp_solver
1050
+ sage: from sage.numerical.backends.generic_backend import get_solver
1051
+ sage: p = MixedIntegerLinearProgram(solver="Nonexistent_LP_solver")
1052
+ sage: b = p.new_variable()
1053
+ sage: p.add_constraint(b[1] + b[2] <= 6)
1054
+ sage: p.set_objective(b[1] + b[2])
1055
+ sage: cp = deepcopy(p.get_backend())
1056
+ sage: cp.solve()
1057
+ 0
1058
+ sage: cp.get_objective_value()
1059
+ 6.0
1060
+ """
1061
+ return self.__copy__()
1062
+
1063
+ cpdef row(self, int i):
1064
+ """
1065
+ Return a row.
1066
+
1067
+ INPUT:
1068
+
1069
+ - ``index`` -- integer; the constraint's id
1070
+
1071
+ OUTPUT:
1072
+
1073
+ A pair ``(indices, coeffs)`` where ``indices`` lists the
1074
+ entries whose coefficient is nonzero, and to which ``coeffs``
1075
+ associates their coefficient on the model of the
1076
+ ``add_linear_constraint`` method.
1077
+
1078
+ EXAMPLES::
1079
+
1080
+ sage: # optional - nonexistent_lp_solver
1081
+ sage: from sage.numerical.backends.generic_backend import get_solver
1082
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
1083
+ sage: p.add_variables(5)
1084
+ 4
1085
+ sage: p.add_linear_constraint(zip(range(5), range(5)), 2, 2)
1086
+ sage: p.row(0)
1087
+ ([4, 3, 2, 1], [4.0, 3.0, 2.0, 1.0]) ## FIXME: Why backwards?
1088
+ sage: p.row_bounds(0)
1089
+ (2.0, 2.0)
1090
+ """
1091
+ raise NotImplementedError()
1092
+
1093
+ cpdef row_bounds(self, int index):
1094
+ """
1095
+ Return the bounds of a specific constraint.
1096
+
1097
+ INPUT:
1098
+
1099
+ - ``index`` -- integer; the constraint's id
1100
+
1101
+ OUTPUT:
1102
+
1103
+ A pair ``(lower_bound, upper_bound)``. Each of them can be set
1104
+ to ``None`` if the constraint is not bounded in the
1105
+ corresponding direction, and is a real value otherwise.
1106
+
1107
+ EXAMPLES::
1108
+
1109
+ sage: # optional - nonexistent_lp_solver
1110
+ sage: from sage.numerical.backends.generic_backend import get_solver
1111
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
1112
+ sage: p.add_variables(5)
1113
+ 4
1114
+ sage: p.add_linear_constraint(list(range(5)), list(range(5)), 2, 2)
1115
+ sage: p.row(0)
1116
+ ([4, 3, 2, 1], [4.0, 3.0, 2.0, 1.0]) ## FIXME: Why backwards?
1117
+ sage: p.row_bounds(0)
1118
+ (2.0, 2.0)
1119
+ """
1120
+ raise NotImplementedError()
1121
+
1122
+ cpdef col_bounds(self, int index):
1123
+ """
1124
+ Return the bounds of a specific variable.
1125
+
1126
+ INPUT:
1127
+
1128
+ - ``index`` -- integer; the variable's id
1129
+
1130
+ OUTPUT:
1131
+
1132
+ A pair ``(lower_bound, upper_bound)``. Each of them can be set
1133
+ to ``None`` if the variable is not bounded in the
1134
+ corresponding direction, and is a real value otherwise.
1135
+
1136
+ EXAMPLES::
1137
+
1138
+ sage: # optional - nonexistent_lp_solver
1139
+ sage: from sage.numerical.backends.generic_backend import get_solver
1140
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
1141
+ sage: p.add_variable()
1142
+ 0
1143
+ sage: p.col_bounds(0)
1144
+ (0.0, None)
1145
+ sage: p.variable_upper_bound(0, 5)
1146
+ sage: p.col_bounds(0)
1147
+ (0.0, 5.0)
1148
+ """
1149
+ raise NotImplementedError()
1150
+
1151
+ cpdef bint is_variable_binary(self, int index) noexcept:
1152
+ """
1153
+ Test whether the given variable is of binary type.
1154
+
1155
+ INPUT:
1156
+
1157
+ - ``index`` -- integer; the variable's id
1158
+
1159
+ EXAMPLES::
1160
+
1161
+ sage: # optional - nonexistent_lp_solver
1162
+ sage: from sage.numerical.backends.generic_backend import get_solver
1163
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
1164
+ sage: p.ncols()
1165
+ 0
1166
+ sage: p.add_variable()
1167
+ 0
1168
+ sage: p.set_variable_type(0,0)
1169
+ sage: p.is_variable_binary(0)
1170
+ True
1171
+ """
1172
+ raise NotImplementedError()
1173
+
1174
+ cpdef bint is_variable_integer(self, int index) noexcept:
1175
+ """
1176
+ Test whether the given variable is of integer type.
1177
+
1178
+ INPUT:
1179
+
1180
+ - ``index`` -- integer; the variable's id
1181
+
1182
+ EXAMPLES::
1183
+
1184
+ sage: # optional - nonexistent_lp_solver
1185
+ sage: from sage.numerical.backends.generic_backend import get_solver
1186
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
1187
+ sage: p.ncols()
1188
+ 0
1189
+ sage: p.add_variable()
1190
+ 0
1191
+ sage: p.set_variable_type(0,1)
1192
+ sage: p.is_variable_integer(0)
1193
+ True
1194
+ """
1195
+ raise NotImplementedError()
1196
+
1197
+ cpdef bint is_variable_continuous(self, int index) noexcept:
1198
+ """
1199
+ Test whether the given variable is of continuous/real type.
1200
+
1201
+ INPUT:
1202
+
1203
+ - ``index`` -- integer; the variable's id
1204
+
1205
+ EXAMPLES::
1206
+
1207
+ sage: # optional - nonexistent_lp_solver
1208
+ sage: from sage.numerical.backends.generic_backend import get_solver
1209
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
1210
+ sage: p.ncols()
1211
+ 0
1212
+ sage: p.add_variable()
1213
+ 0
1214
+ sage: p.is_variable_continuous(0)
1215
+ True
1216
+ sage: p.set_variable_type(0,1)
1217
+ sage: p.is_variable_continuous(0)
1218
+ False
1219
+ """
1220
+ raise NotImplementedError()
1221
+
1222
+ cpdef row_name(self, int index):
1223
+ """
1224
+ Return the ``index``-th row name.
1225
+
1226
+ INPUT:
1227
+
1228
+ - ``index`` -- integer; the row's id
1229
+
1230
+ EXAMPLES::
1231
+
1232
+ sage: # optional - nonexistent_lp_solver
1233
+ sage: from sage.numerical.backends.generic_backend import get_solver
1234
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
1235
+ sage: p.add_linear_constraints(1, 2, None, names=['Empty constraint 1'])
1236
+ sage: p.row_name(0)
1237
+ 'Empty constraint 1'
1238
+ """
1239
+ raise NotImplementedError()
1240
+
1241
+ cpdef col_name(self, int index):
1242
+ """
1243
+ Return the ``index``-th column name.
1244
+
1245
+ INPUT:
1246
+
1247
+ - ``index`` -- integer; the column id
1248
+
1249
+ - ``name`` -- (``char *``) its name; when set to ``NULL``
1250
+ (default), the method returns the current name
1251
+
1252
+ EXAMPLES::
1253
+
1254
+ sage: # optional - nonexistent_lp_solver
1255
+ sage: from sage.numerical.backends.generic_backend import get_solver
1256
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
1257
+ sage: p.add_variable(name="I am a variable")
1258
+ 1
1259
+ sage: p.col_name(0)
1260
+ 'I am a variable'
1261
+ """
1262
+ raise NotImplementedError()
1263
+
1264
+ def _do_test_problem_data(self, tester, cp):
1265
+ """
1266
+ TESTS:
1267
+
1268
+ Test, with an actual working backend, that comparing a problem with itself works::
1269
+
1270
+ sage: from sage.numerical.backends.generic_backend import get_solver
1271
+ sage: p = get_solver(solver='GLPK')
1272
+ sage: tester = p._tester()
1273
+ sage: p._do_test_problem_data(tester, p)
1274
+ """
1275
+ tester.assertEqual(type(self), type(cp),
1276
+ "Classes do not match")
1277
+
1278
+ def assert_equal_problem_data(method):
1279
+ tester.assertEqual(getattr(self, method)(), getattr(cp, method)(),
1280
+ "{} does not match".format(method))
1281
+ for method in ("ncols", "nrows", "objective_constant_term", "problem_name", "is_maximization"):
1282
+ assert_equal_problem_data(method)
1283
+
1284
+ def assert_equal_col_data(method):
1285
+ for i in range(self.ncols()):
1286
+ tester.assertEqual(getattr(self, method)(i), getattr(cp, method)(i),
1287
+ "{}({}) does not match".format(method, i))
1288
+ for method in ("objective_coefficient", "is_variable_binary", "is_variable_binary", "is_variable_integer",
1289
+ "is_variable_continuous", "col_bounds", "col_name"):
1290
+ # don't test variable_lower_bound, variable_upper_bound because we already test col_bounds.
1291
+ # TODO: Add a test elsewhere to ensure that variable_lower_bound, variable_upper_bound
1292
+ # are consistent with col_bounds.
1293
+ assert_equal_col_data(method)
1294
+
1295
+ def assert_equal_row_data(method):
1296
+ for i in range(self.nrows()):
1297
+ tester.assertEqual(getattr(self, method)(i), getattr(cp, method)(i),
1298
+ "{}({}) does not match".format(method, i))
1299
+ for method in ("row_bounds", "row", "row_name"):
1300
+ assert_equal_row_data(method)
1301
+
1302
+ def _test_copy(self, **options):
1303
+ """
1304
+ Test whether the backend can be copied
1305
+ and at least the problem data of the copy is equal to that of the original.
1306
+ Does not test whether solutions or solver parameters are copied.
1307
+ """
1308
+ tester = self._tester(**options)
1309
+ cp = copy(self)
1310
+ self._do_test_problem_data(tester, cp)
1311
+
1312
+ def _test_copy_does_not_share_data(self, **options):
1313
+ """
1314
+ Test whether copy makes an independent copy of the backend.
1315
+ """
1316
+ tester = self._tester(**options)
1317
+
1318
+ cp = copy(self)
1319
+ cpcp = copy(cp)
1320
+ del cp
1321
+ self._do_test_problem_data(tester, cpcp)
1322
+
1323
+ # TODO: We should have a more systematic way of generating MIPs for testing.
1324
+
1325
+ @classmethod
1326
+ def _test_copy_some_mips(cls, tester=None, **options):
1327
+ p = cls() # fresh instance of the backend
1328
+ if tester is None:
1329
+ tester = p._tester(**options)
1330
+ # From doctest of GenericBackend.solve:
1331
+ p.add_linear_constraints(5, 0, None)
1332
+ try:
1333
+ # p.add_col(range(5), range(5)) -- bad test because COIN sparsifies the 0s away on copy
1334
+ p.add_col(list(range(5)), list(range(1, 6)))
1335
+ except NotImplementedError:
1336
+ # Gurobi does not implement add_col
1337
+ pass
1338
+ # From doctest of GenericBackend.problem_name:
1339
+ p.problem_name("There once was a french fry")
1340
+
1341
+ p._test_copy(**options)
1342
+ p._test_copy_does_not_share_data(**options)
1343
+
1344
+ cpdef variable_upper_bound(self, int index, value=False):
1345
+ """
1346
+ Return or define the upper bound on a variable.
1347
+
1348
+ INPUT:
1349
+
1350
+ - ``index`` -- integer; the variable's id
1351
+
1352
+ - ``value`` -- real value, or ``None`` to mean that the
1353
+ variable has not upper bound. When set to ``False``
1354
+ (default), the method returns the current value.
1355
+
1356
+ EXAMPLES::
1357
+
1358
+ sage: # optional - nonexistent_lp_solver
1359
+ sage: from sage.numerical.backends.generic_backend import get_solver
1360
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
1361
+ sage: p.add_variable()
1362
+ 0
1363
+ sage: p.col_bounds(0)
1364
+ (0.0, None)
1365
+ sage: p.variable_upper_bound(0, 5)
1366
+ sage: p.col_bounds(0)
1367
+ (0.0, 5.0)
1368
+ """
1369
+ raise NotImplementedError()
1370
+
1371
+ cpdef variable_lower_bound(self, int index, value=False):
1372
+ """
1373
+ Return or define the lower bound on a variable.
1374
+
1375
+ INPUT:
1376
+
1377
+ - ``index`` -- integer; the variable's id
1378
+
1379
+ - ``value`` -- real value, or ``None`` to mean that the
1380
+ variable has not lower bound. When set to ``False``
1381
+ (default), the method returns the current value.
1382
+
1383
+ EXAMPLES::
1384
+
1385
+ sage: # optional - nonexistent_lp_solver
1386
+ sage: from sage.numerical.backends.generic_backend import get_solver
1387
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
1388
+ sage: p.add_variable()
1389
+ 0
1390
+ sage: p.col_bounds(0)
1391
+ (0.0, None)
1392
+ sage: p.variable_lower_bound(0, 5)
1393
+ sage: p.col_bounds(0)
1394
+ (5.0, None)
1395
+ """
1396
+ raise NotImplementedError()
1397
+
1398
+ cpdef solver_parameter(self, name, value=None):
1399
+ """
1400
+ Return or define a solver parameter.
1401
+
1402
+ INPUT:
1403
+
1404
+ - ``name`` -- string; the parameter
1405
+
1406
+ - ``value`` -- the parameter's value if it is to be defined,
1407
+ or ``None`` (default) to obtain its current value
1408
+
1409
+ .. NOTE::
1410
+
1411
+ The list of available parameters is available at
1412
+ :meth:`~sage.numerical.mip.MixedIntegerLinearProgram.solver_parameter`.
1413
+
1414
+ EXAMPLES::
1415
+
1416
+ sage: # optional - nonexistent_lp_solver
1417
+ sage: from sage.numerical.backends.generic_backend import get_solver
1418
+ sage: p = get_solver(solver="Nonexistent_LP_solver")
1419
+ sage: p.solver_parameter("timelimit")
1420
+ sage: p.solver_parameter("timelimit", 60)
1421
+ sage: p.solver_parameter("timelimit")
1422
+ """
1423
+ raise NotImplementedError()
1424
+
1425
+ cpdef bint is_variable_basic(self, int index) noexcept:
1426
+ """
1427
+ Test whether the given variable is basic.
1428
+
1429
+ This assumes that the problem has been solved with the simplex method
1430
+ and a basis is available. Otherwise an exception will be raised.
1431
+
1432
+ INPUT:
1433
+
1434
+ - ``index`` -- integer; the variable's id
1435
+
1436
+ EXAMPLES::
1437
+
1438
+ sage: # optional - nonexistent_lp_solver
1439
+ sage: p = MixedIntegerLinearProgram(maximization=True,
1440
+ ....: solver="Nonexistent_LP_solver")
1441
+ sage: x = p.new_variable(nonnegative=True)
1442
+ sage: p.add_constraint(-x[0] + x[1] <= 2)
1443
+ sage: p.add_constraint(8 * x[0] + 2 * x[1] <= 17)
1444
+ sage: p.set_objective(5.5 * x[0] - 3 * x[1])
1445
+ sage: b = p.get_backend()
1446
+ sage: # Backend-specific commands to instruct solver to use simplex method here
1447
+ sage: b.solve()
1448
+ 0
1449
+ sage: b.is_variable_basic(0)
1450
+ True
1451
+ sage: b.is_variable_basic(1)
1452
+ False
1453
+ """
1454
+ raise NotImplementedError()
1455
+
1456
+ cpdef bint is_variable_nonbasic_at_lower_bound(self, int index) noexcept:
1457
+ """
1458
+ Test whether the given variable is nonbasic at lower bound.
1459
+
1460
+ This assumes that the problem has been solved with the simplex method
1461
+ and a basis is available. Otherwise an exception will be raised.
1462
+
1463
+ INPUT:
1464
+
1465
+ - ``index`` -- integer; the variable's id
1466
+
1467
+ EXAMPLES::
1468
+
1469
+ sage: # optional - nonexistent_lp_solver
1470
+ sage: p = MixedIntegerLinearProgram(maximization=True,
1471
+ ....: solver="Nonexistent_LP_solver")
1472
+ sage: x = p.new_variable(nonnegative=True)
1473
+ sage: p.add_constraint(-x[0] + x[1] <= 2)
1474
+ sage: p.add_constraint(8 * x[0] + 2 * x[1] <= 17)
1475
+ sage: p.set_objective(5.5 * x[0] - 3 * x[1])
1476
+ sage: b = p.get_backend()
1477
+ sage: # Backend-specific commands to instruct solver to use simplex method here
1478
+ sage: b.solve()
1479
+ 0
1480
+ sage: b.is_variable_nonbasic_at_lower_bound(0)
1481
+ False
1482
+ sage: b.is_variable_nonbasic_at_lower_bound(1)
1483
+ True
1484
+ """
1485
+ raise NotImplementedError()
1486
+
1487
+ cpdef bint is_slack_variable_basic(self, int index) noexcept:
1488
+ """
1489
+ Test whether the slack variable of the given row is basic.
1490
+
1491
+ This assumes that the problem has been solved with the simplex method
1492
+ and a basis is available. Otherwise an exception will be raised.
1493
+
1494
+ INPUT:
1495
+
1496
+ - ``index`` -- integer; the variable's id
1497
+
1498
+ EXAMPLES::
1499
+
1500
+ sage: # optional - nonexistent_lp_solver
1501
+ sage: p = MixedIntegerLinearProgram(maximization=True,
1502
+ ....: solver="Nonexistent_LP_solver")
1503
+ sage: x = p.new_variable(nonnegative=True)
1504
+ sage: p.add_constraint(-x[0] + x[1] <= 2)
1505
+ sage: p.add_constraint(8 * x[0] + 2 * x[1] <= 17)
1506
+ sage: p.set_objective(5.5 * x[0] - 3 * x[1])
1507
+ sage: b = p.get_backend()
1508
+ sage: # Backend-specific commands to instruct solver to use simplex method here
1509
+ sage: b.solve()
1510
+ 0
1511
+ sage: b.is_slack_variable_basic(0)
1512
+ True
1513
+ sage: b.is_slack_variable_basic(1)
1514
+ False
1515
+ """
1516
+ raise NotImplementedError()
1517
+
1518
+ cpdef bint is_slack_variable_nonbasic_at_lower_bound(self, int index) noexcept:
1519
+ """
1520
+ Test whether the given variable is nonbasic at lower bound.
1521
+
1522
+ This assumes that the problem has been solved with the simplex method
1523
+ and a basis is available. Otherwise an exception will be raised.
1524
+
1525
+ INPUT:
1526
+
1527
+ - ``index`` -- integer; the variable's id
1528
+
1529
+ EXAMPLES::
1530
+
1531
+ sage: # optional - nonexistent_lp_solver
1532
+ sage: p = MixedIntegerLinearProgram(maximization=True,
1533
+ ....: solver="Nonexistent_LP_solver")
1534
+ sage: x = p.new_variable(nonnegative=True)
1535
+ sage: p.add_constraint(-x[0] + x[1] <= 2)
1536
+ sage: p.add_constraint(8 * x[0] + 2 * x[1] <= 17)
1537
+ sage: p.set_objective(5.5 * x[0] - 3 * x[1])
1538
+ sage: b = p.get_backend()
1539
+ sage: # Backend-specific commands to instruct solver to use simplex method here
1540
+ sage: b.solve()
1541
+ 0
1542
+ sage: b.is_slack_variable_nonbasic_at_lower_bound(0)
1543
+ False
1544
+ sage: b.is_slack_variable_nonbasic_at_lower_bound(1)
1545
+ True
1546
+ """
1547
+ raise NotImplementedError()
1548
+
1549
+ @classmethod
1550
+ def _test_solve_trac_18572(cls, tester=None, **options):
1551
+ """
1552
+ Run tests regarding :issue:`18572`::
1553
+
1554
+ TESTS::
1555
+
1556
+ sage: from sage.numerical.backends.generic_backend import GenericBackend
1557
+ sage: p = GenericBackend()
1558
+ sage: p._test_solve_trac_18572()
1559
+ Traceback (most recent call last):
1560
+ ...
1561
+ NotImplementedError
1562
+ """
1563
+ p = cls() # fresh instance of the backend
1564
+ if tester is None:
1565
+ tester = p._tester(**options)
1566
+ tester.assertIsNone(p.set_sense(-1))
1567
+ tester.assertEqual(p.add_variable(0, None, False, True, False, 0, None), 0)
1568
+ tester.assertIsNone(p.set_variable_type(0, -1))
1569
+ tester.assertEqual(p.add_variable(0, None, False, True, False, 0, None), 1)
1570
+ tester.assertIsNone(p.set_variable_type(1, -1))
1571
+ tester.assertEqual(p.add_variable(None, None, False, True, False, 0, None), 2)
1572
+ tester.assertIsNone(p.set_variable_type(2, -1))
1573
+ tester.assertIsNone(p.add_linear_constraint([(0, 2), (1, 1), (2, -1)], None, 0, None))
1574
+ tester.assertIsNone(p.add_linear_constraint([(0, 1), (1, 3), (2, -1)], None, 0, None))
1575
+ tester.assertIsNone(p.add_linear_constraint([(0, 1), (1, 1)], 1, 1, None))
1576
+ tester.assertEqual(p.ncols(), 3)
1577
+ tester.assertIsNone(p.set_objective([0, 0, 1], 0))
1578
+ tester.assertEqual(p.solve(), 0)
1579
+ tester.assertAlmostEqual(p.get_objective_value(), 1.66666666667)
1580
+ tester.assertAlmostEqual(p.get_variable_value(0), 0.666666666667)
1581
+ tester.assertAlmostEqual(p.get_variable_value(1), 0.333333333333)
1582
+
1583
+
1584
+ default_solver = None
1585
+
1586
+
1587
+ def default_mip_solver(solver=None):
1588
+ """
1589
+ Return/set the default MILP solver used by Sage.
1590
+
1591
+ INPUT:
1592
+
1593
+ - ``solver`` -- one of the following:
1594
+
1595
+ - a string indicating one of the available solvers
1596
+ (see :class:`MixedIntegerLinearProgram`);
1597
+
1598
+ - a callable (typically a subclass of
1599
+ :class:`sage.numerical.backends.generic_backend.GenericBackend`);
1600
+
1601
+ - ``None`` -- (default) in which case the current default solver
1602
+ is returned; this is either a string or a callable
1603
+
1604
+ OUTPUT:
1605
+
1606
+ This function returns the current default solver's name if ``solver = None``
1607
+ (default). Otherwise, it sets the default solver to the one given. If this
1608
+ solver does not exist, or is not available, a :exc:`ValueError` exception is
1609
+ raised.
1610
+
1611
+ EXAMPLES::
1612
+
1613
+ sage: former_solver = default_mip_solver()
1614
+ sage: default_mip_solver("GLPK")
1615
+ sage: default_mip_solver()
1616
+ 'Glpk'
1617
+ sage: default_mip_solver("PPL")
1618
+ sage: default_mip_solver()
1619
+ 'Ppl'
1620
+ sage: default_mip_solver("GUROBI") # random
1621
+ Traceback (most recent call last):
1622
+ ...
1623
+ ValueError: Gurobi is not available. Please refer to the documentation to install it.
1624
+ sage: default_mip_solver("Yeahhhhhhhhhhh")
1625
+ Traceback (most recent call last):
1626
+ ...
1627
+ ValueError: 'solver' should be set to ...
1628
+ sage: default_mip_solver(former_solver)
1629
+ """
1630
+ global default_solver
1631
+
1632
+ if solver is None:
1633
+
1634
+ if default_solver is not None:
1635
+ return default_solver
1636
+
1637
+ else:
1638
+ for s in ["Cplex", "Gurobi", "Cvxpy/cbc", "Coin", "Glpk", "SCIP"]:
1639
+ try:
1640
+ default_mip_solver(s)
1641
+ return s
1642
+ except ValueError:
1643
+ pass
1644
+
1645
+ if callable(solver):
1646
+ default_solver = solver
1647
+ return
1648
+
1649
+ solver = solver.capitalize()
1650
+
1651
+ if solver == "Cplex":
1652
+ try:
1653
+ from sage_numerical_backends_cplex.cplex_backend import CPLEXBackend
1654
+ default_solver = solver
1655
+ except ImportError:
1656
+ raise ValueError("CPLEX is not available. Please refer to the documentation to install it.")
1657
+
1658
+ elif solver == "Coin":
1659
+ try:
1660
+ from sage_numerical_backends_coin.coin_backend import CoinBackend
1661
+ default_solver = solver
1662
+ except ImportError:
1663
+ raise ValueError("COIN is not available. Please refer to the documentation to install it.")
1664
+
1665
+ elif solver == "Cvxopt":
1666
+ try:
1667
+ from sage.numerical.backends.cvxopt_backend import CVXOPTBackend
1668
+ default_solver = solver
1669
+ except ImportError:
1670
+ raise ValueError("CVXOPT is not available. Please refer to the documentation to install it.")
1671
+
1672
+ elif solver == "Ppl":
1673
+ try:
1674
+ from sage.numerical.backends.ppl_backend import PPLBackend
1675
+ default_solver = solver
1676
+ except ImportError:
1677
+ raise ValueError("PPL is not available. Please refer to the documentation to install it.")
1678
+
1679
+ elif solver == "Gurobi":
1680
+ try:
1681
+ from sage_numerical_backends_gurobi.gurobi_backend import GurobiBackend
1682
+ default_solver = solver
1683
+ except ImportError:
1684
+ raise ValueError("Gurobi is not available. Please refer to the documentation to install it.")
1685
+
1686
+ elif solver == "Glpk" or solver == "Glpk/exact":
1687
+ try:
1688
+ from sage.numerical.backends.glpk_backend import GLPKBackend
1689
+ default_solver = solver
1690
+ except ImportError:
1691
+ raise ValueError("GLPK is not available. Please refer to the documentation to install it.")
1692
+
1693
+ elif solver == "Interactivelp":
1694
+ default_solver = solver
1695
+
1696
+ elif solver == "Cvxpy":
1697
+ try:
1698
+ from sage.numerical.backends.cvxpy_backend import CVXPYBackend
1699
+ except ImportError:
1700
+ raise ValueError("CVXPY is not available. Please refer to the documentation to install it.")
1701
+ else:
1702
+ assert CVXPYBackend
1703
+ default_solver = solver
1704
+
1705
+ elif solver.startswith("Cvxpy"):
1706
+ try:
1707
+ s = get_solver(solver=solver)
1708
+ s.solve()
1709
+ except Exception as e:
1710
+ raise ValueError(f"{solver} is not available: {e}. Please refer to the documentation to install it.")
1711
+ else:
1712
+ default_solver = solver
1713
+
1714
+ elif solver == "Scip":
1715
+ try:
1716
+ from sage.numerical.backends.scip_backend import SCIPBackend
1717
+ default_solver = solver
1718
+ except ImportError:
1719
+ raise ValueError("SCIP is not available. Please refer to the documentation to install it.")
1720
+
1721
+ else:
1722
+ raise ValueError("'solver' should be set to 'GLPK', 'Coin', 'CPLEX', 'CVXOPT', 'CVXPY', 'Gurobi', 'PPL', 'SCIP', 'InteractiveLP', a callable, or None.")
1723
+
1724
+
1725
+ cpdef GenericBackend get_solver(constraint_generation=False, solver=None, base_ring=None):
1726
+ """
1727
+ Return a solver according to the given preferences.
1728
+
1729
+ INPUT:
1730
+
1731
+ - ``solver`` -- one of the following:
1732
+
1733
+ - a string indicating one of the available solvers
1734
+ (see :class:`MixedIntegerLinearProgram`);
1735
+
1736
+ - ``None`` -- (default) in which case the default solver is used
1737
+ (see :func:`default_mip_solver`);
1738
+
1739
+ - or a callable (such as a class), in which case it is called,
1740
+ and its result is returned.
1741
+
1742
+ - ``base_ring`` -- if not ``None``, request a solver that works over this
1743
+ (ordered) field. If ``base_ring`` is not a field, its fraction field
1744
+ is used.
1745
+
1746
+ For example, is ``base_ring=ZZ`` is provided, the solver will work over
1747
+ the rational numbers. This is unrelated to whether variables are
1748
+ constrained to be integers or not.
1749
+
1750
+ - ``constraint_generation`` -- only used when ``solver=None``:
1751
+
1752
+ - When set to ``True``, after solving the ``MixedIntegerLinearProgram``,
1753
+ it is possible to add a constraint, and then solve it again.
1754
+ The effect is that solvers that do not support this feature will not be
1755
+ used. (Coin and SCIP are such solvers.)
1756
+
1757
+ - Defaults to ``False``.
1758
+
1759
+ .. SEEALSO::
1760
+
1761
+ - :func:`default_mip_solver` -- returns/sets the default MIP solver
1762
+
1763
+ EXAMPLES::
1764
+
1765
+ sage: from sage.numerical.backends.generic_backend import get_solver
1766
+ sage: p = get_solver()
1767
+ sage: p = get_solver(base_ring=RDF)
1768
+ sage: p.base_ring()
1769
+ Real Double Field
1770
+ sage: p = get_solver(base_ring=QQ); p
1771
+ <...sage.numerical.backends.ppl_backend.PPLBackend...>
1772
+ sage: p = get_solver(base_ring=ZZ); p
1773
+ <...sage.numerical.backends.ppl_backend.PPLBackend...>
1774
+ sage: p.base_ring()
1775
+ Rational Field
1776
+ sage: p = get_solver(base_ring=AA); p # needs sage.rings.number_field
1777
+ <...sage.numerical.backends.interactivelp_backend.InteractiveLPBackend...>
1778
+ sage: p.base_ring() # needs sage.rings.number_field
1779
+ Algebraic Real Field
1780
+
1781
+ sage: # needs sage.groups sage.rings.number_field
1782
+ sage: d = polytopes.dodecahedron()
1783
+ sage: p = get_solver(base_ring=d.base_ring()); p
1784
+ <...sage.numerical.backends.interactivelp_backend.InteractiveLPBackend...>
1785
+ sage: p.base_ring()
1786
+ Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790?
1787
+ sage: p = get_solver(solver='InteractiveLP', base_ring=QQ); p
1788
+ <...sage.numerical.backends.interactivelp_backend.InteractiveLPBackend...>
1789
+ sage: p.base_ring()
1790
+ Rational Field
1791
+
1792
+ Passing a callable as the ``solver``::
1793
+
1794
+ sage: from sage.numerical.backends.glpk_backend import GLPKBackend
1795
+ sage: p = get_solver(solver=GLPKBackend); p
1796
+ <...sage.numerical.backends.glpk_backend.GLPKBackend...>
1797
+
1798
+ Passing a callable that customizes a backend::
1799
+
1800
+ sage: def glpk_exact_solver():
1801
+ ....: from sage.numerical.backends.generic_backend import get_solver
1802
+ ....: b = get_solver(solver='GLPK')
1803
+ ....: b.solver_parameter('simplex_or_intopt', 'exact_simplex_only')
1804
+ ....: return b
1805
+ sage: codes.bounds.delsarte_bound_additive_hamming_space(11,3,4,solver=glpk_exact_solver) # long time
1806
+ 8
1807
+
1808
+ TESTS:
1809
+
1810
+ Test that it works when the default solver is a callable, see :issue:`28914`::
1811
+
1812
+ sage: old_default = default_mip_solver()
1813
+ sage: from sage.numerical.backends.glpk_backend import GLPKBackend
1814
+ sage: default_mip_solver(GLPKBackend)
1815
+ sage: M = MixedIntegerLinearProgram() # indirect doctest
1816
+ sage: M.get_backend()
1817
+ <...GLPKBackend...>
1818
+ sage: default_mip_solver(old_default)
1819
+ """
1820
+ if solver is None:
1821
+
1822
+ solver = default_mip_solver()
1823
+
1824
+ if base_ring is not None:
1825
+ base_ring = base_ring.fraction_field()
1826
+ from sage.rings.rational_field import QQ
1827
+ from sage.rings.real_double import RDF
1828
+ if base_ring is QQ:
1829
+ solver = "Ppl"
1830
+ elif solver in ["Interactivelp", "Ppl"] and not base_ring.is_exact():
1831
+ solver = "Glpk"
1832
+ elif base_ring is not RDF:
1833
+ solver = "Interactivelp"
1834
+
1835
+ # We do not want to use Coin for constraint_generation. It just does not
1836
+ # work
1837
+ if solver in ("Coin", "SCIP") and constraint_generation:
1838
+ solver = "Glpk"
1839
+
1840
+ if callable(solver):
1841
+ kwds = {}
1842
+ if base_ring is not None:
1843
+ kwds['base_ring']=base_ring
1844
+ return solver(**kwds)
1845
+
1846
+ else:
1847
+ solver = solver.capitalize()
1848
+
1849
+ if solver == "Coin":
1850
+ from sage_numerical_backends_coin.coin_backend import CoinBackend
1851
+ return CoinBackend()
1852
+
1853
+ elif solver == "Glpk":
1854
+ from sage.numerical.backends.glpk_backend import GLPKBackend
1855
+ return GLPKBackend()
1856
+
1857
+ elif solver == "Glpk/exact":
1858
+ from sage.numerical.backends.glpk_exact_backend import GLPKExactBackend
1859
+ return GLPKExactBackend()
1860
+
1861
+ elif solver == "Cplex":
1862
+ from sage_numerical_backends_cplex.cplex_backend import CPLEXBackend
1863
+ return CPLEXBackend()
1864
+
1865
+ elif solver == "Cvxopt":
1866
+ from sage.numerical.backends.cvxopt_backend import CVXOPTBackend
1867
+ return CVXOPTBackend()
1868
+
1869
+ elif solver == "Gurobi":
1870
+ from sage_numerical_backends_gurobi.gurobi_backend import GurobiBackend
1871
+ return GurobiBackend()
1872
+
1873
+ elif solver == "Ppl":
1874
+ from sage.numerical.backends.ppl_backend import PPLBackend
1875
+ return PPLBackend(base_ring=base_ring)
1876
+
1877
+ elif solver == "Interactivelp":
1878
+ from sage.numerical.backends.interactivelp_backend import InteractiveLPBackend
1879
+ return InteractiveLPBackend(base_ring=base_ring)
1880
+
1881
+ elif solver.startswith("Cvxpy"):
1882
+ from sage.numerical.backends.cvxpy_backend import CVXPYBackend
1883
+ if solver == "Cvxpy":
1884
+ return CVXPYBackend()
1885
+ if solver.startswith("Cvxpy/"):
1886
+ return CVXPYBackend(cvxpy_solver=solver[len("Cvxpy/"):])
1887
+
1888
+ elif solver == "Scip":
1889
+ from sage.numerical.backends.scip_backend import SCIPBackend
1890
+ return SCIPBackend()
1891
+
1892
+ else:
1893
+ raise ValueError("'solver' should be set to 'GLPK', 'GLPK/exact', 'Coin', 'CPLEX', 'CVXOPT', 'CVXPY', 'Gurobi', 'PPL', 'SCIP', 'InteractiveLP', None (in which case the default one is used), or a callable.")