test_eigen_symmetric.py 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. from mpmath import mp
  4. from mpmath import libmp
  5. xrange = libmp.backend.xrange
  6. def run_eigsy(A, verbose = False):
  7. if verbose:
  8. print("original matrix:\n", str(A))
  9. D, Q = mp.eigsy(A)
  10. B = Q * mp.diag(D) * Q.transpose()
  11. C = A - B
  12. E = Q * Q.transpose() - mp.eye(A.rows)
  13. if verbose:
  14. print("eigenvalues:\n", D)
  15. print("eigenvectors:\n", Q)
  16. NC = mp.mnorm(C)
  17. NE = mp.mnorm(E)
  18. if verbose:
  19. print("difference:", NC, "\n", C, "\n")
  20. print("difference:", NE, "\n", E, "\n")
  21. eps = mp.exp( 0.8 * mp.log(mp.eps))
  22. assert NC < eps
  23. assert NE < eps
  24. return NC
  25. def run_eighe(A, verbose = False):
  26. if verbose:
  27. print("original matrix:\n", str(A))
  28. D, Q = mp.eighe(A)
  29. B = Q * mp.diag(D) * Q.transpose_conj()
  30. C = A - B
  31. E = Q * Q.transpose_conj() - mp.eye(A.rows)
  32. if verbose:
  33. print("eigenvalues:\n", D)
  34. print("eigenvectors:\n", Q)
  35. NC = mp.mnorm(C)
  36. NE = mp.mnorm(E)
  37. if verbose:
  38. print("difference:", NC, "\n", C, "\n")
  39. print("difference:", NE, "\n", E, "\n")
  40. eps = mp.exp( 0.8 * mp.log(mp.eps))
  41. assert NC < eps
  42. assert NE < eps
  43. return NC
  44. def run_svd_r(A, full_matrices = False, verbose = True):
  45. m, n = A.rows, A.cols
  46. eps = mp.exp(0.8 * mp.log(mp.eps))
  47. if verbose:
  48. print("original matrix:\n", str(A))
  49. print("full", full_matrices)
  50. U, S0, V = mp.svd_r(A, full_matrices = full_matrices)
  51. S = mp.zeros(U.cols, V.rows)
  52. for j in xrange(min(m, n)):
  53. S[j,j] = S0[j]
  54. if verbose:
  55. print("U:\n", str(U))
  56. print("S:\n", str(S0))
  57. print("V:\n", str(V))
  58. C = U * S * V - A
  59. err = mp.mnorm(C)
  60. if verbose:
  61. print("C\n", str(C), "\n", err)
  62. assert err < eps
  63. D = V * V.transpose() - mp.eye(V.rows)
  64. err = mp.mnorm(D)
  65. if verbose:
  66. print("D:\n", str(D), "\n", err)
  67. assert err < eps
  68. E = U.transpose() * U - mp.eye(U.cols)
  69. err = mp.mnorm(E)
  70. if verbose:
  71. print("E:\n", str(E), "\n", err)
  72. assert err < eps
  73. def run_svd_c(A, full_matrices = False, verbose = True):
  74. m, n = A.rows, A.cols
  75. eps = mp.exp(0.8 * mp.log(mp.eps))
  76. if verbose:
  77. print("original matrix:\n", str(A))
  78. print("full", full_matrices)
  79. U, S0, V = mp.svd_c(A, full_matrices = full_matrices)
  80. S = mp.zeros(U.cols, V.rows)
  81. for j in xrange(min(m, n)):
  82. S[j,j] = S0[j]
  83. if verbose:
  84. print("U:\n", str(U))
  85. print("S:\n", str(S0))
  86. print("V:\n", str(V))
  87. C = U * S * V - A
  88. err = mp.mnorm(C)
  89. if verbose:
  90. print("C\n", str(C), "\n", err)
  91. assert err < eps
  92. D = V * V.transpose_conj() - mp.eye(V.rows)
  93. err = mp.mnorm(D)
  94. if verbose:
  95. print("D:\n", str(D), "\n", err)
  96. assert err < eps
  97. E = U.transpose_conj() * U - mp.eye(U.cols)
  98. err = mp.mnorm(E)
  99. if verbose:
  100. print("E:\n", str(E), "\n", err)
  101. assert err < eps
  102. def run_gauss(qtype, a, b):
  103. eps = 1e-5
  104. d, e = mp.gauss_quadrature(len(a), qtype)
  105. d -= mp.matrix(a)
  106. e -= mp.matrix(b)
  107. assert mp.mnorm(d) < eps
  108. assert mp.mnorm(e) < eps
  109. def irandmatrix(n, range = 10):
  110. """
  111. random matrix with integer entries
  112. """
  113. A = mp.matrix(n, n)
  114. for i in xrange(n):
  115. for j in xrange(n):
  116. A[i,j]=int( (2 * mp.rand() - 1) * range)
  117. return A
  118. #######################
  119. def test_eighe_fixed_matrix():
  120. A = mp.matrix([[2, 3], [3, 5]])
  121. run_eigsy(A)
  122. run_eighe(A)
  123. A = mp.matrix([[7, -11], [-11, 13]])
  124. run_eigsy(A)
  125. run_eighe(A)
  126. A = mp.matrix([[2, 11, 7], [11, 3, 13], [7, 13, 5]])
  127. run_eigsy(A)
  128. run_eighe(A)
  129. A = mp.matrix([[2, 0, 7], [0, 3, 1], [7, 1, 5]])
  130. run_eigsy(A)
  131. run_eighe(A)
  132. #
  133. A = mp.matrix([[2, 3+7j], [3-7j, 5]])
  134. run_eighe(A)
  135. A = mp.matrix([[2, -11j, 0], [+11j, 3, 29j], [0, -29j, 5]])
  136. run_eighe(A)
  137. A = mp.matrix([[2, 11 + 17j, 7 + 19j], [11 - 17j, 3, -13 + 23j], [7 - 19j, -13 - 23j, 5]])
  138. run_eighe(A)
  139. def test_eigsy_randmatrix():
  140. N = 5
  141. for a in xrange(10):
  142. A = 2 * mp.randmatrix(N, N) - 1
  143. for i in xrange(0, N):
  144. for j in xrange(i + 1, N):
  145. A[j,i] = A[i,j]
  146. run_eigsy(A)
  147. def test_eighe_randmatrix():
  148. N = 5
  149. for a in xrange(10):
  150. A = (2 * mp.randmatrix(N, N) - 1) + 1j * (2 * mp.randmatrix(N, N) - 1)
  151. for i in xrange(0, N):
  152. A[i,i] = mp.re(A[i,i])
  153. for j in xrange(i + 1, N):
  154. A[j,i] = mp.conj(A[i,j])
  155. run_eighe(A)
  156. def test_eigsy_irandmatrix():
  157. N = 4
  158. R = 4
  159. for a in xrange(10):
  160. A=irandmatrix(N, R)
  161. for i in xrange(0, N):
  162. for j in xrange(i + 1, N):
  163. A[j,i] = A[i,j]
  164. run_eigsy(A)
  165. def test_eighe_irandmatrix():
  166. N = 4
  167. R = 4
  168. for a in xrange(10):
  169. A=irandmatrix(N, R) + 1j * irandmatrix(N, R)
  170. for i in xrange(0, N):
  171. A[i,i] = mp.re(A[i,i])
  172. for j in xrange(i + 1, N):
  173. A[j,i] = mp.conj(A[i,j])
  174. run_eighe(A)
  175. def test_svd_r_rand():
  176. for i in xrange(5):
  177. full = mp.rand() > 0.5
  178. m = 1 + int(mp.rand() * 10)
  179. n = 1 + int(mp.rand() * 10)
  180. A = 2 * mp.randmatrix(m, n) - 1
  181. if mp.rand() > 0.5:
  182. A *= 10
  183. for x in xrange(m):
  184. for y in xrange(n):
  185. A[x,y]=int(A[x,y])
  186. run_svd_r(A, full_matrices = full, verbose = False)
  187. def test_svd_c_rand():
  188. for i in xrange(5):
  189. full = mp.rand() > 0.5
  190. m = 1 + int(mp.rand() * 10)
  191. n = 1 + int(mp.rand() * 10)
  192. A = (2 * mp.randmatrix(m, n) - 1) + 1j * (2 * mp.randmatrix(m, n) - 1)
  193. if mp.rand() > 0.5:
  194. A *= 10
  195. for x in xrange(m):
  196. for y in xrange(n):
  197. A[x,y]=int(mp.re(A[x,y])) + 1j * int(mp.im(A[x,y]))
  198. run_svd_c(A, full_matrices=full, verbose=False)
  199. def test_svd_test_case():
  200. # a test case from Golub and Reinsch
  201. # (see wilkinson/reinsch: handbook for auto. comp., vol ii-linear algebra, 134-151(1971).)
  202. eps = mp.exp(0.8 * mp.log(mp.eps))
  203. a = [[22, 10, 2, 3, 7],
  204. [14, 7, 10, 0, 8],
  205. [-1, 13, -1, -11, 3],
  206. [-3, -2, 13, -2, 4],
  207. [ 9, 8, 1, -2, 4],
  208. [ 9, 1, -7, 5, -1],
  209. [ 2, -6, 6, 5, 1],
  210. [ 4, 5, 0, -2, 2]]
  211. a = mp.matrix(a)
  212. b = mp.matrix([mp.sqrt(1248), 20, mp.sqrt(384), 0, 0])
  213. S = mp.svd_r(a, compute_uv = False)
  214. S -= b
  215. assert mp.mnorm(S) < eps
  216. S = mp.svd_c(a, compute_uv = False)
  217. S -= b
  218. assert mp.mnorm(S) < eps
  219. def test_gauss_quadrature_static():
  220. a = [-0.57735027, 0.57735027]
  221. b = [ 1, 1]
  222. run_gauss("legendre", a , b)
  223. a = [ -0.906179846, -0.538469310, 0, 0.538469310, 0.906179846]
  224. b = [ 0.23692689, 0.47862867, 0.56888889, 0.47862867, 0.23692689]
  225. run_gauss("legendre", a , b)
  226. a = [ 0.06943184, 0.33000948, 0.66999052, 0.93056816]
  227. b = [ 0.17392742, 0.32607258, 0.32607258, 0.17392742]
  228. run_gauss("legendre01", a , b)
  229. a = [-0.70710678, 0.70710678]
  230. b = [ 0.88622693, 0.88622693]
  231. run_gauss("hermite", a , b)
  232. a = [ -2.02018287, -0.958572465, 0, 0.958572465, 2.02018287]
  233. b = [ 0.01995324, 0.39361932, 0.94530872, 0.39361932, 0.01995324]
  234. run_gauss("hermite", a , b)
  235. a = [ 0.41577456, 2.29428036, 6.28994508]
  236. b = [ 0.71109301, 0.27851773, 0.01038926]
  237. run_gauss("laguerre", a , b)
  238. def test_gauss_quadrature_dynamic(verbose = False):
  239. n = 5
  240. A = mp.randmatrix(2 * n, 1)
  241. def F(x):
  242. r = 0
  243. for i in xrange(len(A) - 1, -1, -1):
  244. r = r * x + A[i]
  245. return r
  246. def run(qtype, FW, R, alpha = 0, beta = 0):
  247. X, W = mp.gauss_quadrature(n, qtype, alpha = alpha, beta = beta)
  248. a = 0
  249. for i in xrange(len(X)):
  250. a += W[i] * F(X[i])
  251. b = mp.quad(lambda x: FW(x) * F(x), R)
  252. c = mp.fabs(a - b)
  253. if verbose:
  254. print(qtype, c, a, b)
  255. assert c < 1e-5
  256. run("legendre", lambda x: 1, [-1, 1])
  257. run("legendre01", lambda x: 1, [0, 1])
  258. run("hermite", lambda x: mp.exp(-x*x), [-mp.inf, mp.inf])
  259. run("laguerre", lambda x: mp.exp(-x), [0, mp.inf])
  260. run("glaguerre", lambda x: mp.sqrt(x)*mp.exp(-x), [0, mp.inf], alpha = 1 / mp.mpf(2))
  261. run("chebyshev1", lambda x: 1/mp.sqrt(1-x*x), [-1, 1])
  262. run("chebyshev2", lambda x: mp.sqrt(1-x*x), [-1, 1])
  263. run("jacobi", lambda x: (1-x)**(1/mp.mpf(3)) * (1+x)**(1/mp.mpf(5)), [-1, 1], alpha = 1 / mp.mpf(3), beta = 1 / mp.mpf(5) )