test_projections.py 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. import numpy as np
  2. import scipy.linalg
  3. from scipy.sparse import csc_matrix
  4. from scipy.optimize._trustregion_constr.projections \
  5. import projections, orthogonality
  6. from numpy.testing import (TestCase, assert_array_almost_equal,
  7. assert_equal, assert_allclose)
  8. try:
  9. from sksparse.cholmod import cholesky_AAt
  10. sksparse_available = True
  11. available_sparse_methods = ("NormalEquation", "AugmentedSystem")
  12. except ImportError:
  13. sksparse_available = False
  14. available_sparse_methods = ("AugmentedSystem",)
  15. available_dense_methods = ('QRFactorization', 'SVDFactorization')
  16. class TestProjections(TestCase):
  17. def test_nullspace_and_least_squares_sparse(self):
  18. A_dense = np.array([[1, 2, 3, 4, 0, 5, 0, 7],
  19. [0, 8, 7, 0, 1, 5, 9, 0],
  20. [1, 0, 0, 0, 0, 1, 2, 3]])
  21. At_dense = A_dense.T
  22. A = csc_matrix(A_dense)
  23. test_points = ([1, 2, 3, 4, 5, 6, 7, 8],
  24. [1, 10, 3, 0, 1, 6, 7, 8],
  25. [1.12, 10, 0, 0, 100000, 6, 0.7, 8])
  26. for method in available_sparse_methods:
  27. Z, LS, _ = projections(A, method)
  28. for z in test_points:
  29. # Test if x is in the null_space
  30. x = Z.matvec(z)
  31. assert_array_almost_equal(A.dot(x), 0)
  32. # Test orthogonality
  33. assert_array_almost_equal(orthogonality(A, x), 0)
  34. # Test if x is the least square solution
  35. x = LS.matvec(z)
  36. x2 = scipy.linalg.lstsq(At_dense, z)[0]
  37. assert_array_almost_equal(x, x2)
  38. def test_iterative_refinements_sparse(self):
  39. A_dense = np.array([[1, 2, 3, 4, 0, 5, 0, 7],
  40. [0, 8, 7, 0, 1, 5, 9, 0],
  41. [1, 0, 0, 0, 0, 1, 2, 3]])
  42. A = csc_matrix(A_dense)
  43. test_points = ([1, 2, 3, 4, 5, 6, 7, 8],
  44. [1, 10, 3, 0, 1, 6, 7, 8],
  45. [1.12, 10, 0, 0, 100000, 6, 0.7, 8],
  46. [1, 0, 0, 0, 0, 1, 2, 3+1e-10])
  47. for method in available_sparse_methods:
  48. Z, LS, _ = projections(A, method, orth_tol=1e-18, max_refin=100)
  49. for z in test_points:
  50. # Test if x is in the null_space
  51. x = Z.matvec(z)
  52. atol = 1e-13 * abs(x).max()
  53. assert_allclose(A.dot(x), 0, atol=atol)
  54. # Test orthogonality
  55. assert_allclose(orthogonality(A, x), 0, atol=1e-13)
  56. def test_rowspace_sparse(self):
  57. A_dense = np.array([[1, 2, 3, 4, 0, 5, 0, 7],
  58. [0, 8, 7, 0, 1, 5, 9, 0],
  59. [1, 0, 0, 0, 0, 1, 2, 3]])
  60. A = csc_matrix(A_dense)
  61. test_points = ([1, 2, 3],
  62. [1, 10, 3],
  63. [1.12, 10, 0])
  64. for method in available_sparse_methods:
  65. _, _, Y = projections(A, method)
  66. for z in test_points:
  67. # Test if x is solution of A x = z
  68. x = Y.matvec(z)
  69. assert_array_almost_equal(A.dot(x), z)
  70. # Test if x is in the return row space of A
  71. A_ext = np.vstack((A_dense, x))
  72. assert_equal(np.linalg.matrix_rank(A_dense),
  73. np.linalg.matrix_rank(A_ext))
  74. def test_nullspace_and_least_squares_dense(self):
  75. A = np.array([[1, 2, 3, 4, 0, 5, 0, 7],
  76. [0, 8, 7, 0, 1, 5, 9, 0],
  77. [1, 0, 0, 0, 0, 1, 2, 3]])
  78. At = A.T
  79. test_points = ([1, 2, 3, 4, 5, 6, 7, 8],
  80. [1, 10, 3, 0, 1, 6, 7, 8],
  81. [1.12, 10, 0, 0, 100000, 6, 0.7, 8])
  82. for method in available_dense_methods:
  83. Z, LS, _ = projections(A, method)
  84. for z in test_points:
  85. # Test if x is in the null_space
  86. x = Z.matvec(z)
  87. assert_array_almost_equal(A.dot(x), 0)
  88. # Test orthogonality
  89. assert_array_almost_equal(orthogonality(A, x), 0)
  90. # Test if x is the least square solution
  91. x = LS.matvec(z)
  92. x2 = scipy.linalg.lstsq(At, z)[0]
  93. assert_array_almost_equal(x, x2)
  94. def test_compare_dense_and_sparse(self):
  95. D = np.diag(range(1, 101))
  96. A = np.hstack([D, D, D, D])
  97. A_sparse = csc_matrix(A)
  98. np.random.seed(0)
  99. Z, LS, Y = projections(A)
  100. Z_sparse, LS_sparse, Y_sparse = projections(A_sparse)
  101. for k in range(20):
  102. z = np.random.normal(size=(400,))
  103. assert_array_almost_equal(Z.dot(z), Z_sparse.dot(z))
  104. assert_array_almost_equal(LS.dot(z), LS_sparse.dot(z))
  105. x = np.random.normal(size=(100,))
  106. assert_array_almost_equal(Y.dot(x), Y_sparse.dot(x))
  107. def test_compare_dense_and_sparse2(self):
  108. D1 = np.diag([-1.7, 1, 0.5])
  109. D2 = np.diag([1, -0.6, -0.3])
  110. D3 = np.diag([-0.3, -1.5, 2])
  111. A = np.hstack([D1, D2, D3])
  112. A_sparse = csc_matrix(A)
  113. np.random.seed(0)
  114. Z, LS, Y = projections(A)
  115. Z_sparse, LS_sparse, Y_sparse = projections(A_sparse)
  116. for k in range(1):
  117. z = np.random.normal(size=(9,))
  118. assert_array_almost_equal(Z.dot(z), Z_sparse.dot(z))
  119. assert_array_almost_equal(LS.dot(z), LS_sparse.dot(z))
  120. x = np.random.normal(size=(3,))
  121. assert_array_almost_equal(Y.dot(x), Y_sparse.dot(x))
  122. def test_iterative_refinements_dense(self):
  123. A = np.array([[1, 2, 3, 4, 0, 5, 0, 7],
  124. [0, 8, 7, 0, 1, 5, 9, 0],
  125. [1, 0, 0, 0, 0, 1, 2, 3]])
  126. test_points = ([1, 2, 3, 4, 5, 6, 7, 8],
  127. [1, 10, 3, 0, 1, 6, 7, 8],
  128. [1, 0, 0, 0, 0, 1, 2, 3+1e-10])
  129. for method in available_dense_methods:
  130. Z, LS, _ = projections(A, method, orth_tol=1e-18, max_refin=10)
  131. for z in test_points:
  132. # Test if x is in the null_space
  133. x = Z.matvec(z)
  134. assert_allclose(A.dot(x), 0, rtol=0, atol=2.5e-14)
  135. # Test orthogonality
  136. assert_allclose(orthogonality(A, x), 0, rtol=0, atol=5e-16)
  137. def test_rowspace_dense(self):
  138. A = np.array([[1, 2, 3, 4, 0, 5, 0, 7],
  139. [0, 8, 7, 0, 1, 5, 9, 0],
  140. [1, 0, 0, 0, 0, 1, 2, 3]])
  141. test_points = ([1, 2, 3],
  142. [1, 10, 3],
  143. [1.12, 10, 0])
  144. for method in available_dense_methods:
  145. _, _, Y = projections(A, method)
  146. for z in test_points:
  147. # Test if x is solution of A x = z
  148. x = Y.matvec(z)
  149. assert_array_almost_equal(A.dot(x), z)
  150. # Test if x is in the return row space of A
  151. A_ext = np.vstack((A, x))
  152. assert_equal(np.linalg.matrix_rank(A),
  153. np.linalg.matrix_rank(A_ext))
  154. class TestOrthogonality(TestCase):
  155. def test_dense_matrix(self):
  156. A = np.array([[1, 2, 3, 4, 0, 5, 0, 7],
  157. [0, 8, 7, 0, 1, 5, 9, 0],
  158. [1, 0, 0, 0, 0, 1, 2, 3]])
  159. test_vectors = ([-1.98931144, -1.56363389,
  160. -0.84115584, 2.2864762,
  161. 5.599141, 0.09286976,
  162. 1.37040802, -0.28145812],
  163. [697.92794044, -4091.65114008,
  164. -3327.42316335, 836.86906951,
  165. 99434.98929065, -1285.37653682,
  166. -4109.21503806, 2935.29289083])
  167. test_expected_orth = (0, 0)
  168. for i in range(len(test_vectors)):
  169. x = test_vectors[i]
  170. orth = test_expected_orth[i]
  171. assert_array_almost_equal(orthogonality(A, x), orth)
  172. def test_sparse_matrix(self):
  173. A = np.array([[1, 2, 3, 4, 0, 5, 0, 7],
  174. [0, 8, 7, 0, 1, 5, 9, 0],
  175. [1, 0, 0, 0, 0, 1, 2, 3]])
  176. A = csc_matrix(A)
  177. test_vectors = ([-1.98931144, -1.56363389,
  178. -0.84115584, 2.2864762,
  179. 5.599141, 0.09286976,
  180. 1.37040802, -0.28145812],
  181. [697.92794044, -4091.65114008,
  182. -3327.42316335, 836.86906951,
  183. 99434.98929065, -1285.37653682,
  184. -4109.21503806, 2935.29289083])
  185. test_expected_orth = (0, 0)
  186. for i in range(len(test_vectors)):
  187. x = test_vectors[i]
  188. orth = test_expected_orth[i]
  189. assert_array_almost_equal(orthogonality(A, x), orth)