test_lsmr.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. """
  2. Copyright (C) 2010 David Fong and Michael Saunders
  3. Distributed under the same license as Scipy
  4. Testing Code for LSMR.
  5. 03 Jun 2010: First version release with lsmr.py
  6. David Chin-lung Fong clfong@stanford.edu
  7. Institute for Computational and Mathematical Engineering
  8. Stanford University
  9. Michael Saunders saunders@stanford.edu
  10. Systems Optimization Laboratory
  11. Dept of MS&E, Stanford University.
  12. """
  13. from __future__ import division, print_function, absolute_import
  14. from numpy import array, arange, eye, zeros, ones, sqrt, transpose, hstack
  15. from numpy.linalg import norm
  16. from numpy.testing import (assert_almost_equal,
  17. assert_array_almost_equal)
  18. from scipy.sparse import coo_matrix
  19. from scipy.sparse.linalg.interface import aslinearoperator
  20. from scipy.sparse.linalg import lsmr
  21. from .test_lsqr import G, b
  22. class TestLSMR:
  23. def setup_method(self):
  24. self.n = 10
  25. self.m = 10
  26. def assertCompatibleSystem(self, A, xtrue):
  27. Afun = aslinearoperator(A)
  28. b = Afun.matvec(xtrue)
  29. x = lsmr(A, b)[0]
  30. assert_almost_equal(norm(x - xtrue), 0, decimal=5)
  31. def testIdentityACase1(self):
  32. A = eye(self.n)
  33. xtrue = zeros((self.n, 1))
  34. self.assertCompatibleSystem(A, xtrue)
  35. def testIdentityACase2(self):
  36. A = eye(self.n)
  37. xtrue = ones((self.n,1))
  38. self.assertCompatibleSystem(A, xtrue)
  39. def testIdentityACase3(self):
  40. A = eye(self.n)
  41. xtrue = transpose(arange(self.n,0,-1))
  42. self.assertCompatibleSystem(A, xtrue)
  43. def testBidiagonalA(self):
  44. A = lowerBidiagonalMatrix(20,self.n)
  45. xtrue = transpose(arange(self.n,0,-1))
  46. self.assertCompatibleSystem(A,xtrue)
  47. def testScalarB(self):
  48. A = array([[1.0, 2.0]])
  49. b = 3.0
  50. x = lsmr(A, b)[0]
  51. assert_almost_equal(norm(A.dot(x) - b), 0)
  52. def testColumnB(self):
  53. A = eye(self.n)
  54. b = ones((self.n, 1))
  55. x = lsmr(A, b)[0]
  56. assert_almost_equal(norm(A.dot(x) - b.ravel()), 0)
  57. def testInitialization(self):
  58. # Test that the default setting is not modified
  59. x_ref = lsmr(G, b)[0]
  60. x0 = zeros(b.shape)
  61. x = lsmr(G, b, x0=x0)[0]
  62. assert_array_almost_equal(x_ref, x)
  63. # Test warm-start with single iteration
  64. x0 = lsmr(G, b, maxiter=1)[0]
  65. x = lsmr(G, b, x0=x0)[0]
  66. assert_array_almost_equal(x_ref, x)
  67. class TestLSMRReturns:
  68. def setup_method(self):
  69. self.n = 10
  70. self.A = lowerBidiagonalMatrix(20,self.n)
  71. self.xtrue = transpose(arange(self.n,0,-1))
  72. self.Afun = aslinearoperator(self.A)
  73. self.b = self.Afun.matvec(self.xtrue)
  74. self.returnValues = lsmr(self.A,self.b)
  75. def testNormr(self):
  76. x, istop, itn, normr, normar, normA, condA, normx = self.returnValues
  77. assert_almost_equal(normr, norm(self.b - self.Afun.matvec(x)))
  78. def testNormar(self):
  79. x, istop, itn, normr, normar, normA, condA, normx = self.returnValues
  80. assert_almost_equal(normar,
  81. norm(self.Afun.rmatvec(self.b - self.Afun.matvec(x))))
  82. def testNormx(self):
  83. x, istop, itn, normr, normar, normA, condA, normx = self.returnValues
  84. assert_almost_equal(normx, norm(x))
  85. def lowerBidiagonalMatrix(m, n):
  86. # This is a simple example for testing LSMR.
  87. # It uses the leading m*n submatrix from
  88. # A = [ 1
  89. # 1 2
  90. # 2 3
  91. # 3 4
  92. # ...
  93. # n ]
  94. # suitably padded by zeros.
  95. #
  96. # 04 Jun 2010: First version for distribution with lsmr.py
  97. if m <= n:
  98. row = hstack((arange(m, dtype=int),
  99. arange(1, m, dtype=int)))
  100. col = hstack((arange(m, dtype=int),
  101. arange(m-1, dtype=int)))
  102. data = hstack((arange(1, m+1, dtype=float),
  103. arange(1,m, dtype=float)))
  104. return coo_matrix((data, (row, col)), shape=(m,n))
  105. else:
  106. row = hstack((arange(n, dtype=int),
  107. arange(1, n+1, dtype=int)))
  108. col = hstack((arange(n, dtype=int),
  109. arange(n, dtype=int)))
  110. data = hstack((arange(1, n+1, dtype=float),
  111. arange(1,n+1, dtype=float)))
  112. return coo_matrix((data,(row, col)), shape=(m,n))
  113. def lsmrtest(m, n, damp):
  114. """Verbose testing of lsmr"""
  115. A = lowerBidiagonalMatrix(m,n)
  116. xtrue = arange(n,0,-1, dtype=float)
  117. Afun = aslinearoperator(A)
  118. b = Afun.matvec(xtrue)
  119. atol = 1.0e-7
  120. btol = 1.0e-7
  121. conlim = 1.0e+10
  122. itnlim = 10*n
  123. show = 1
  124. x, istop, itn, normr, normar, norma, conda, normx \
  125. = lsmr(A, b, damp, atol, btol, conlim, itnlim, show)
  126. j1 = min(n,5)
  127. j2 = max(n-4,1)
  128. print(' ')
  129. print('First elements of x:')
  130. str = ['%10.4f' % (xi) for xi in x[0:j1]]
  131. print(''.join(str))
  132. print(' ')
  133. print('Last elements of x:')
  134. str = ['%10.4f' % (xi) for xi in x[j2-1:]]
  135. print(''.join(str))
  136. r = b - Afun.matvec(x)
  137. r2 = sqrt(norm(r)**2 + (damp*norm(x))**2)
  138. print(' ')
  139. str = 'normr (est.) %17.10e' % (normr)
  140. str2 = 'normr (true) %17.10e' % (r2)
  141. print(str)
  142. print(str2)
  143. print(' ')
  144. if __name__ == "__main__":
  145. lsmrtest(20,10,0)