test_decomp_cholesky.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. from __future__ import division, print_function, absolute_import
  2. from numpy.testing import assert_array_almost_equal, assert_array_equal
  3. from pytest import raises as assert_raises
  4. from numpy import array, transpose, dot, conjugate, zeros_like, empty
  5. from numpy.random import random
  6. from scipy.linalg import cholesky, cholesky_banded, cho_solve_banded, \
  7. cho_factor, cho_solve
  8. from scipy.linalg._testutils import assert_no_overwrite
  9. class TestCholesky(object):
  10. def test_simple(self):
  11. a = [[8, 2, 3], [2, 9, 3], [3, 3, 6]]
  12. c = cholesky(a)
  13. assert_array_almost_equal(dot(transpose(c), c), a)
  14. c = transpose(c)
  15. a = dot(c, transpose(c))
  16. assert_array_almost_equal(cholesky(a, lower=1), c)
  17. def test_check_finite(self):
  18. a = [[8, 2, 3], [2, 9, 3], [3, 3, 6]]
  19. c = cholesky(a, check_finite=False)
  20. assert_array_almost_equal(dot(transpose(c), c), a)
  21. c = transpose(c)
  22. a = dot(c, transpose(c))
  23. assert_array_almost_equal(cholesky(a, lower=1, check_finite=False), c)
  24. def test_simple_complex(self):
  25. m = array([[3+1j, 3+4j, 5], [0, 2+2j, 2+7j], [0, 0, 7+4j]])
  26. a = dot(transpose(conjugate(m)), m)
  27. c = cholesky(a)
  28. a1 = dot(transpose(conjugate(c)), c)
  29. assert_array_almost_equal(a, a1)
  30. c = transpose(c)
  31. a = dot(c, transpose(conjugate(c)))
  32. assert_array_almost_equal(cholesky(a, lower=1), c)
  33. def test_random(self):
  34. n = 20
  35. for k in range(2):
  36. m = random([n, n])
  37. for i in range(n):
  38. m[i, i] = 20*(.1+m[i, i])
  39. a = dot(transpose(m), m)
  40. c = cholesky(a)
  41. a1 = dot(transpose(c), c)
  42. assert_array_almost_equal(a, a1)
  43. c = transpose(c)
  44. a = dot(c, transpose(c))
  45. assert_array_almost_equal(cholesky(a, lower=1), c)
  46. def test_random_complex(self):
  47. n = 20
  48. for k in range(2):
  49. m = random([n, n])+1j*random([n, n])
  50. for i in range(n):
  51. m[i, i] = 20*(.1+abs(m[i, i]))
  52. a = dot(transpose(conjugate(m)), m)
  53. c = cholesky(a)
  54. a1 = dot(transpose(conjugate(c)), c)
  55. assert_array_almost_equal(a, a1)
  56. c = transpose(c)
  57. a = dot(c, transpose(conjugate(c)))
  58. assert_array_almost_equal(cholesky(a, lower=1), c)
  59. class TestCholeskyBanded(object):
  60. """Tests for cholesky_banded() and cho_solve_banded."""
  61. def test_check_finite(self):
  62. # Symmetric positive definite banded matrix `a`
  63. a = array([[4.0, 1.0, 0.0, 0.0],
  64. [1.0, 4.0, 0.5, 0.0],
  65. [0.0, 0.5, 4.0, 0.2],
  66. [0.0, 0.0, 0.2, 4.0]])
  67. # Banded storage form of `a`.
  68. ab = array([[-1.0, 1.0, 0.5, 0.2],
  69. [4.0, 4.0, 4.0, 4.0]])
  70. c = cholesky_banded(ab, lower=False, check_finite=False)
  71. ufac = zeros_like(a)
  72. ufac[list(range(4)), list(range(4))] = c[-1]
  73. ufac[(0, 1, 2), (1, 2, 3)] = c[0, 1:]
  74. assert_array_almost_equal(a, dot(ufac.T, ufac))
  75. b = array([0.0, 0.5, 4.2, 4.2])
  76. x = cho_solve_banded((c, False), b, check_finite=False)
  77. assert_array_almost_equal(x, [0.0, 0.0, 1.0, 1.0])
  78. def test_upper_real(self):
  79. # Symmetric positive definite banded matrix `a`
  80. a = array([[4.0, 1.0, 0.0, 0.0],
  81. [1.0, 4.0, 0.5, 0.0],
  82. [0.0, 0.5, 4.0, 0.2],
  83. [0.0, 0.0, 0.2, 4.0]])
  84. # Banded storage form of `a`.
  85. ab = array([[-1.0, 1.0, 0.5, 0.2],
  86. [4.0, 4.0, 4.0, 4.0]])
  87. c = cholesky_banded(ab, lower=False)
  88. ufac = zeros_like(a)
  89. ufac[list(range(4)), list(range(4))] = c[-1]
  90. ufac[(0, 1, 2), (1, 2, 3)] = c[0, 1:]
  91. assert_array_almost_equal(a, dot(ufac.T, ufac))
  92. b = array([0.0, 0.5, 4.2, 4.2])
  93. x = cho_solve_banded((c, False), b)
  94. assert_array_almost_equal(x, [0.0, 0.0, 1.0, 1.0])
  95. def test_upper_complex(self):
  96. # Hermitian positive definite banded matrix `a`
  97. a = array([[4.0, 1.0, 0.0, 0.0],
  98. [1.0, 4.0, 0.5, 0.0],
  99. [0.0, 0.5, 4.0, -0.2j],
  100. [0.0, 0.0, 0.2j, 4.0]])
  101. # Banded storage form of `a`.
  102. ab = array([[-1.0, 1.0, 0.5, -0.2j],
  103. [4.0, 4.0, 4.0, 4.0]])
  104. c = cholesky_banded(ab, lower=False)
  105. ufac = zeros_like(a)
  106. ufac[list(range(4)), list(range(4))] = c[-1]
  107. ufac[(0, 1, 2), (1, 2, 3)] = c[0, 1:]
  108. assert_array_almost_equal(a, dot(ufac.conj().T, ufac))
  109. b = array([0.0, 0.5, 4.0-0.2j, 0.2j + 4.0])
  110. x = cho_solve_banded((c, False), b)
  111. assert_array_almost_equal(x, [0.0, 0.0, 1.0, 1.0])
  112. def test_lower_real(self):
  113. # Symmetric positive definite banded matrix `a`
  114. a = array([[4.0, 1.0, 0.0, 0.0],
  115. [1.0, 4.0, 0.5, 0.0],
  116. [0.0, 0.5, 4.0, 0.2],
  117. [0.0, 0.0, 0.2, 4.0]])
  118. # Banded storage form of `a`.
  119. ab = array([[4.0, 4.0, 4.0, 4.0],
  120. [1.0, 0.5, 0.2, -1.0]])
  121. c = cholesky_banded(ab, lower=True)
  122. lfac = zeros_like(a)
  123. lfac[list(range(4)), list(range(4))] = c[0]
  124. lfac[(1, 2, 3), (0, 1, 2)] = c[1, :3]
  125. assert_array_almost_equal(a, dot(lfac, lfac.T))
  126. b = array([0.0, 0.5, 4.2, 4.2])
  127. x = cho_solve_banded((c, True), b)
  128. assert_array_almost_equal(x, [0.0, 0.0, 1.0, 1.0])
  129. def test_lower_complex(self):
  130. # Hermitian positive definite banded matrix `a`
  131. a = array([[4.0, 1.0, 0.0, 0.0],
  132. [1.0, 4.0, 0.5, 0.0],
  133. [0.0, 0.5, 4.0, -0.2j],
  134. [0.0, 0.0, 0.2j, 4.0]])
  135. # Banded storage form of `a`.
  136. ab = array([[4.0, 4.0, 4.0, 4.0],
  137. [1.0, 0.5, 0.2j, -1.0]])
  138. c = cholesky_banded(ab, lower=True)
  139. lfac = zeros_like(a)
  140. lfac[list(range(4)), list(range(4))] = c[0]
  141. lfac[(1, 2, 3), (0, 1, 2)] = c[1, :3]
  142. assert_array_almost_equal(a, dot(lfac, lfac.conj().T))
  143. b = array([0.0, 0.5j, 3.8j, 3.8])
  144. x = cho_solve_banded((c, True), b)
  145. assert_array_almost_equal(x, [0.0, 0.0, 1.0j, 1.0])
  146. class TestOverwrite(object):
  147. def test_cholesky(self):
  148. assert_no_overwrite(cholesky, [(3, 3)])
  149. def test_cho_factor(self):
  150. assert_no_overwrite(cho_factor, [(3, 3)])
  151. def test_cho_solve(self):
  152. x = array([[2, -1, 0], [-1, 2, -1], [0, -1, 2]])
  153. xcho = cho_factor(x)
  154. assert_no_overwrite(lambda b: cho_solve(xcho, b), [(3,)])
  155. def test_cholesky_banded(self):
  156. assert_no_overwrite(cholesky_banded, [(2, 3)])
  157. def test_cho_solve_banded(self):
  158. x = array([[0, -1, -1], [2, 2, 2]])
  159. xcho = cholesky_banded(x)
  160. assert_no_overwrite(lambda b: cho_solve_banded((xcho, False), b),
  161. [(3,)])
  162. class TestEmptyArray(object):
  163. def test_cho_factor_empty_square(self):
  164. a = empty((0, 0))
  165. b = array([])
  166. c = array([[]])
  167. d = []
  168. e = [[]]
  169. x, _ = cho_factor(a)
  170. assert_array_equal(x, a)
  171. for x in ([b, c, d, e]):
  172. assert_raises(ValueError, cho_factor, x)