test__linprog_clean_inputs.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. """
  2. Unit test for Linear Programming via Simplex Algorithm.
  3. """
  4. from __future__ import division, print_function, absolute_import
  5. import numpy as np
  6. from numpy.testing import assert_, assert_allclose
  7. from pytest import raises as assert_raises
  8. from scipy.optimize._linprog_util import _clean_inputs
  9. from copy import deepcopy
  10. def test_aliasing():
  11. c = 1
  12. A_ub = [[1]]
  13. b_ub = [1]
  14. A_eq = [[1]]
  15. b_eq = [1]
  16. bounds = (-np.inf, np.inf)
  17. c_copy = deepcopy(c)
  18. A_ub_copy = deepcopy(A_ub)
  19. b_ub_copy = deepcopy(b_ub)
  20. A_eq_copy = deepcopy(A_eq)
  21. b_eq_copy = deepcopy(b_eq)
  22. bounds_copy = deepcopy(bounds)
  23. _clean_inputs(c, A_ub, b_ub, A_eq, b_eq, bounds)
  24. assert_(c == c_copy, "c modified by _clean_inputs")
  25. assert_(A_ub == A_ub_copy, "A_ub modified by _clean_inputs")
  26. assert_(b_ub == b_ub_copy, "b_ub modified by _clean_inputs")
  27. assert_(A_eq == A_eq_copy, "A_eq modified by _clean_inputs")
  28. assert_(b_eq == b_eq_copy, "b_eq modified by _clean_inputs")
  29. assert_(bounds == bounds_copy, "bounds modified by _clean_inputs")
  30. def test_aliasing2():
  31. c = np.array([1, 1])
  32. A_ub = np.array([[1, 1], [2, 2]])
  33. b_ub = np.array([[1], [1]])
  34. A_eq = np.array([[1, 1]])
  35. b_eq = np.array([1])
  36. bounds = [(-np.inf, np.inf), (None, 1)]
  37. c_copy = c.copy()
  38. A_ub_copy = A_ub.copy()
  39. b_ub_copy = b_ub.copy()
  40. A_eq_copy = A_eq.copy()
  41. b_eq_copy = b_eq.copy()
  42. bounds_copy = deepcopy(bounds)
  43. _clean_inputs(c, A_ub, b_ub, A_eq, b_eq, bounds)
  44. assert_allclose(c, c_copy, err_msg="c modified by _clean_inputs")
  45. assert_allclose(A_ub, A_ub_copy, err_msg="A_ub modified by _clean_inputs")
  46. assert_allclose(b_ub, b_ub_copy, err_msg="b_ub modified by _clean_inputs")
  47. assert_allclose(A_eq, A_eq_copy, err_msg="A_eq modified by _clean_inputs")
  48. assert_allclose(b_eq, b_eq_copy, err_msg="b_eq modified by _clean_inputs")
  49. assert_(bounds == bounds_copy, "bounds modified by _clean_inputs")
  50. def test_missing_inputs():
  51. c = [1, 2]
  52. A_ub = np.array([[1, 1], [2, 2]])
  53. b_ub = np.array([1, 1])
  54. A_eq = np.array([[1, 1], [2, 2]])
  55. b_eq = np.array([1, 1])
  56. assert_raises(TypeError, _clean_inputs)
  57. assert_raises(TypeError, _clean_inputs, c=None)
  58. assert_raises(ValueError, _clean_inputs, c=c, A_ub=A_ub)
  59. assert_raises(ValueError, _clean_inputs, c=c, A_ub=A_ub, b_ub=None)
  60. assert_raises(ValueError, _clean_inputs, c=c, b_ub=b_ub)
  61. assert_raises(ValueError, _clean_inputs, c=c, A_ub=None, b_ub=b_ub)
  62. assert_raises(ValueError, _clean_inputs, c=c, A_eq=A_eq)
  63. assert_raises(ValueError, _clean_inputs, c=c, A_eq=A_eq, b_eq=None)
  64. assert_raises(ValueError, _clean_inputs, c=c, b_eq=b_eq)
  65. assert_raises(ValueError, _clean_inputs, c=c, A_eq=None, b_eq=b_eq)
  66. def test_too_many_dimensions():
  67. cb = [1, 2, 3, 4]
  68. A = np.random.rand(4, 4)
  69. bad2D = [[1, 2], [3, 4]]
  70. bad3D = np.random.rand(4, 4, 4)
  71. assert_raises(ValueError, _clean_inputs, c=bad2D, A_ub=A, b_ub=cb)
  72. assert_raises(ValueError, _clean_inputs, c=cb, A_ub=bad3D, b_ub=cb)
  73. assert_raises(ValueError, _clean_inputs, c=cb, A_ub=A, b_ub=bad2D)
  74. assert_raises(ValueError, _clean_inputs, c=cb, A_eq=bad3D, b_eq=cb)
  75. assert_raises(ValueError, _clean_inputs, c=cb, A_eq=A, b_eq=bad2D)
  76. def test_too_few_dimensions():
  77. bad = np.random.rand(4, 4).ravel()
  78. cb = np.random.rand(4)
  79. assert_raises(ValueError, _clean_inputs, c=cb, A_ub=bad, b_ub=cb)
  80. assert_raises(ValueError, _clean_inputs, c=cb, A_eq=bad, b_eq=cb)
  81. def test_inconsistent_dimensions():
  82. m = 2
  83. n = 4
  84. c = [1, 2, 3, 4]
  85. Agood = np.random.rand(m, n)
  86. Abad = np.random.rand(m, n + 1)
  87. bgood = np.random.rand(m)
  88. bbad = np.random.rand(m + 1)
  89. boundsbad = [(0, 1)] * (n + 1)
  90. assert_raises(ValueError, _clean_inputs, c=c, A_ub=Abad, b_ub=bgood)
  91. assert_raises(ValueError, _clean_inputs, c=c, A_ub=Agood, b_ub=bbad)
  92. assert_raises(ValueError, _clean_inputs, c=c, A_eq=Abad, b_eq=bgood)
  93. assert_raises(ValueError, _clean_inputs, c=c, A_eq=Agood, b_eq=bbad)
  94. assert_raises(ValueError, _clean_inputs, c=c, bounds=boundsbad)
  95. def test_type_errors():
  96. bad = "hello"
  97. c = [1, 2]
  98. A_ub = np.array([[1, 1], [2, 2]])
  99. b_ub = np.array([1, 1])
  100. A_eq = np.array([[1, 1], [2, 2]])
  101. b_eq = np.array([1, 1])
  102. bounds = [(0, 1)]
  103. assert_raises(
  104. TypeError,
  105. _clean_inputs,
  106. c=bad,
  107. A_ub=A_ub,
  108. b_ub=b_ub,
  109. A_eq=A_eq,
  110. b_eq=b_eq,
  111. bounds=bounds)
  112. assert_raises(
  113. TypeError,
  114. _clean_inputs,
  115. c=c,
  116. A_ub=bad,
  117. b_ub=b_ub,
  118. A_eq=A_eq,
  119. b_eq=b_eq,
  120. bounds=bounds)
  121. assert_raises(
  122. TypeError,
  123. _clean_inputs,
  124. c=c,
  125. A_ub=A_ub,
  126. b_ub=bad,
  127. A_eq=A_eq,
  128. b_eq=b_eq,
  129. bounds=bounds)
  130. assert_raises(
  131. TypeError,
  132. _clean_inputs,
  133. c=c,
  134. A_ub=A_ub,
  135. b_ub=b_ub,
  136. A_eq=bad,
  137. b_eq=b_eq,
  138. bounds=bounds)
  139. assert_raises(
  140. TypeError,
  141. _clean_inputs,
  142. c=c,
  143. A_ub=A_ub,
  144. b_ub=b_ub,
  145. A_eq=A_eq,
  146. b_eq=b_eq,
  147. bounds=bad)
  148. assert_raises(
  149. TypeError,
  150. _clean_inputs,
  151. c=c,
  152. A_ub=A_ub,
  153. b_ub=b_ub,
  154. A_eq=A_eq,
  155. b_eq=b_eq,
  156. bounds="hi")
  157. assert_raises(
  158. TypeError,
  159. _clean_inputs,
  160. c=c,
  161. A_ub=A_ub,
  162. b_ub=b_ub,
  163. A_eq=A_eq,
  164. b_eq=b_eq,
  165. bounds=["hi"])
  166. assert_raises(
  167. TypeError,
  168. _clean_inputs,
  169. c=c,
  170. A_ub=A_ub,
  171. b_ub=b_ub,
  172. A_eq=A_eq,
  173. b_eq=b_eq,
  174. bounds=[
  175. ("hi")])
  176. assert_raises(TypeError, _clean_inputs, c=c, A_ub=A_ub,
  177. b_ub=b_ub, A_eq=A_eq, b_eq=b_eq, bounds=[(1, "")])
  178. assert_raises(TypeError, _clean_inputs, c=c, A_ub=A_ub,
  179. b_ub=b_ub, A_eq=A_eq, b_eq=b_eq, bounds=[(1, 2), (1, "")])
  180. def test_non_finite_errors():
  181. c = [1, 2]
  182. A_ub = np.array([[1, 1], [2, 2]])
  183. b_ub = np.array([1, 1])
  184. A_eq = np.array([[1, 1], [2, 2]])
  185. b_eq = np.array([1, 1])
  186. bounds = [(0, 1)]
  187. assert_raises(
  188. ValueError, _clean_inputs, c=[0, None], A_ub=A_ub, b_ub=b_ub,
  189. A_eq=A_eq, b_eq=b_eq, bounds=bounds)
  190. assert_raises(
  191. ValueError, _clean_inputs, c=[np.inf, 0], A_ub=A_ub, b_ub=b_ub,
  192. A_eq=A_eq, b_eq=b_eq, bounds=bounds)
  193. assert_raises(
  194. ValueError, _clean_inputs, c=[0, -np.inf], A_ub=A_ub, b_ub=b_ub,
  195. A_eq=A_eq, b_eq=b_eq, bounds=bounds)
  196. assert_raises(
  197. ValueError, _clean_inputs, c=[np.nan, 0], A_ub=A_ub, b_ub=b_ub,
  198. A_eq=A_eq, b_eq=b_eq, bounds=bounds)
  199. assert_raises(ValueError, _clean_inputs, c=c, A_ub=[[1, 2], [None, 1]],
  200. b_ub=b_ub, A_eq=A_eq, b_eq=b_eq, bounds=bounds)
  201. assert_raises(
  202. ValueError,
  203. _clean_inputs,
  204. c=c,
  205. A_ub=A_ub,
  206. b_ub=[
  207. np.inf,
  208. 1],
  209. A_eq=A_eq,
  210. b_eq=b_eq,
  211. bounds=bounds)
  212. assert_raises(ValueError, _clean_inputs, c=c, A_ub=A_ub, b_ub=b_ub, A_eq=[
  213. [1, 2], [1, -np.inf]], b_eq=b_eq, bounds=bounds)
  214. assert_raises(
  215. ValueError,
  216. _clean_inputs,
  217. c=c,
  218. A_ub=A_ub,
  219. b_ub=b_ub,
  220. A_eq=A_eq,
  221. b_eq=[
  222. 1,
  223. np.nan],
  224. bounds=bounds)
  225. def test__clean_inputs1():
  226. c = [1, 2]
  227. A_ub = [[1, 1], [2, 2]]
  228. b_ub = [1, 1]
  229. A_eq = [[1, 1], [2, 2]]
  230. b_eq = [1, 1]
  231. bounds = None
  232. outputs = _clean_inputs(
  233. c=c,
  234. A_ub=A_ub,
  235. b_ub=b_ub,
  236. A_eq=A_eq,
  237. b_eq=b_eq,
  238. bounds=bounds)
  239. assert_allclose(outputs[0], np.array(c))
  240. assert_allclose(outputs[1], np.array(A_ub))
  241. assert_allclose(outputs[2], np.array(b_ub))
  242. assert_allclose(outputs[3], np.array(A_eq))
  243. assert_allclose(outputs[4], np.array(b_eq))
  244. assert_(outputs[5] == [(0, None)] * 2, "")
  245. assert_(outputs[0].shape == (2,), "")
  246. assert_(outputs[1].shape == (2, 2), "")
  247. assert_(outputs[2].shape == (2,), "")
  248. assert_(outputs[3].shape == (2, 2), "")
  249. assert_(outputs[4].shape == (2,), "")
  250. def test__clean_inputs2():
  251. c = 1
  252. A_ub = [[1]]
  253. b_ub = 1
  254. A_eq = [[1]]
  255. b_eq = 1
  256. bounds = (0, 1)
  257. outputs = _clean_inputs(
  258. c=c,
  259. A_ub=A_ub,
  260. b_ub=b_ub,
  261. A_eq=A_eq,
  262. b_eq=b_eq,
  263. bounds=bounds)
  264. assert_allclose(outputs[0], np.array(c))
  265. assert_allclose(outputs[1], np.array(A_ub))
  266. assert_allclose(outputs[2], np.array(b_ub))
  267. assert_allclose(outputs[3], np.array(A_eq))
  268. assert_allclose(outputs[4], np.array(b_eq))
  269. assert_(outputs[5] == [(0, 1)], "")
  270. assert_(outputs[0].shape == (1,), "")
  271. assert_(outputs[1].shape == (1, 1), "")
  272. assert_(outputs[2].shape == (1,), "")
  273. assert_(outputs[3].shape == (1, 1), "")
  274. assert_(outputs[4].shape == (1,), "")
  275. def test__clean_inputs3():
  276. c = [[1, 2]]
  277. A_ub = np.random.rand(2, 2)
  278. b_ub = [[1], [2]]
  279. A_eq = np.random.rand(2, 2)
  280. b_eq = [[1], [2]]
  281. bounds = [(0, 1)]
  282. outputs = _clean_inputs(
  283. c=c,
  284. A_ub=A_ub,
  285. b_ub=b_ub,
  286. A_eq=A_eq,
  287. b_eq=b_eq,
  288. bounds=bounds)
  289. assert_allclose(outputs[0], np.array([1, 2]))
  290. assert_allclose(outputs[2], np.array([1, 2]))
  291. assert_allclose(outputs[4], np.array([1, 2]))
  292. assert_(outputs[5] == [(0, 1)] * 2, "")
  293. assert_(outputs[0].shape == (2,), "")
  294. assert_(outputs[2].shape == (2,), "")
  295. assert_(outputs[4].shape == (2,), "")
  296. def test_bad_bounds():
  297. c = [1, 2]
  298. assert_raises(ValueError, _clean_inputs, c=c, bounds=(1, -2))
  299. assert_raises(ValueError, _clean_inputs, c=c, bounds=[(1, -2)])
  300. assert_raises(ValueError, _clean_inputs, c=c, bounds=[(1, -2), (1, 2)])
  301. assert_raises(ValueError, _clean_inputs, c=c, bounds=(1, 2, 2))
  302. assert_raises(ValueError, _clean_inputs, c=c, bounds=[(1, 2, 2)])
  303. assert_raises(ValueError, _clean_inputs, c=c, bounds=[(1, 2), (1, 2, 2)])
  304. assert_raises(ValueError, _clean_inputs, c=c,
  305. bounds=[(1, 2), (1, 2), (1, 2)])
  306. def test_good_bounds():
  307. c = [1, 2]
  308. outputs = _clean_inputs(c=c, bounds=None)
  309. assert_(outputs[5] == [(0, None)] * 2, "")
  310. outputs = _clean_inputs(c=c, bounds=(1, 2))
  311. assert_(outputs[5] == [(1, 2)] * 2, "")
  312. outputs = _clean_inputs(c=c, bounds=[(1, 2)])
  313. assert_(outputs[5] == [(1, 2)] * 2, "")
  314. outputs = _clean_inputs(c=c, bounds=[(1, np.inf)])
  315. assert_(outputs[5] == [(1, None)] * 2, "")
  316. outputs = _clean_inputs(c=c, bounds=[(-np.inf, 1)])
  317. assert_(outputs[5] == [(None, 1)] * 2, "")
  318. outputs = _clean_inputs(c=c, bounds=[(-np.inf, np.inf), (-np.inf, np.inf)])
  319. assert_(outputs[5] == [(None, None)] * 2, "")