Advertisement
Guest User

Untitled

a guest
May 21st, 2019
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.57 KB | None | 0 0
  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. import pandas as pd
  4. import tensorflow as tf
  5. from numpy import linalg as la
  6. from scipy.sparse import spdiags
  7.  
  8.  
  9. def jacobi(A, b, x0, max_iter, e, w=1.0):
  10. residual_norm = []
  11. convergence_factor = []
  12.  
  13. k = 0
  14. x = {k: x0}
  15.  
  16. D = np.diagflat(np.diag(A))
  17. LU = A - D
  18. for k in range(1, max_iter):
  19. x[k] = np.dot(1 - w, x[k - 1]) + np.dot(w, np.matmul(la.inv(D), (b - np.matmul(LU, x[k - 1]))))
  20.  
  21. residual_norm.append(la.norm(np.matmul(A, x[k]) - b, ord=2))
  22. convergence_factor.append(la.norm(np.matmul(A, x[k]) - b, ord=2) / la.norm(np.matmul(A, x[k - 1]) - b, ord=2))
  23.  
  24. if la.norm(np.matmul(A, x[k]) - b, ord=2) / la.norm(b, ord=2) < e:
  25. break
  26. return x[k], residual_norm, convergence_factor, k
  27.  
  28.  
  29. def gauss_seidel(A, b, x0, max_iter, e):
  30. residual_norm = []
  31. convergence_factor = []
  32.  
  33. k = 0
  34. x = {k: x0}
  35.  
  36. DL = np.tril(A)
  37. U = A - DL
  38. for k in range(1, max_iter):
  39. x[k] = np.matmul(la.inv(DL), (b - np.matmul(U, x[k - 1])))
  40.  
  41. residual_norm.append(la.norm(np.matmul(A, x[k]) - b, ord=2))
  42. convergence_factor.append(la.norm(np.matmul(A, x[k]) - b, ord=2) / la.norm(np.matmul(A, x[k - 1]) - b, ord=2))
  43.  
  44. if la.norm(np.matmul(A, x[k]) - b, ord=2) / la.norm(b, ord=2) < e:
  45. break
  46. return x[k], residual_norm, convergence_factor, k
  47.  
  48.  
  49. def steepest_descent(A, b, x0, max_iter, e):
  50. residual_norm = []
  51. convergence_factor = []
  52.  
  53. k = 0
  54. r = {}
  55. x = {k: x0}
  56.  
  57. r[0] = b - np.matmul(A, x[0])
  58. for k in range(1, max_iter):
  59. alpha = np.dot(r[k - 1], r[k - 1]) / np.dot(r[k - 1], np.matmul(A, r[k - 1]))
  60. x[k] = x[k - 1] + alpha * r[k - 1]
  61. r[k] = b - np.matmul(A, x[k])
  62.  
  63. residual_norm.append(la.norm(r[k], ord=2))
  64. convergence_factor.append(la.norm(r[k], ord=2) / la.norm(r[k - 1], ord=2))
  65.  
  66. if la.norm(np.matmul(A, x[k]) - b, ord=2) / la.norm(b, ord=2) < e:
  67. break
  68. return x[k], residual_norm, convergence_factor, k
  69.  
  70.  
  71. def conjugate_gradient(A, b, x0, max_iter, e):
  72. residual_norm = []
  73. convergence_factor = []
  74.  
  75. k = 0
  76. p = {}
  77. r = {}
  78. x = {k: x0}
  79.  
  80. p[0] = b - np.matmul(A, x[0])
  81. r[0] = b - np.matmul(A, x[0])
  82. for k in range(1, max_iter):
  83. Ap_k_prev = np.matmul(A, p[k - 1])
  84. alpha = np.dot(r[k - 1], p[k - 1]) / np.dot(p[k - 1], Ap_k_prev)
  85. x[k] = x[k - 1] + alpha * p[k - 1]
  86. r[k] = b - np.matmul(A, x[k])
  87.  
  88. residual_norm.append(la.norm(r[k], ord=2))
  89. convergence_factor.append(la.norm(r[k], ord=2) / la.norm(r[k - 1], ord=2))
  90.  
  91. if la.norm(np.matmul(A, x[k]) - b, ord=2) / la.norm(b, ord=2) < e:
  92. break
  93. beta = -np.dot(r[k], Ap_k_prev) / np.dot(p[k - 1], Ap_k_prev)
  94. p[k] = r[k] + beta * p[k - 1]
  95. return x[k], residual_norm, convergence_factor, k
  96.  
  97.  
  98. def GMRES(A, b, x0, max_iter, e):
  99. residual_norm = []
  100. convergence_factor = []
  101.  
  102. k = 0
  103. r = {}
  104. x = {k: x0}
  105.  
  106. r[0] = b - np.matmul(A, x[0])
  107. for k in range(1, max_iter):
  108. Ar_k = np.matmul(A, r[k - 1])
  109. alpha = np.dot(r[k - 1], Ar_k) / np.dot(Ar_k, Ar_k)
  110. x[k] = x[k - 1] + alpha * r[k - 1]
  111. r[k] = b - np.matmul(A, x[k])
  112.  
  113. residual_norm.append(la.norm(r[k], ord=2))
  114. convergence_factor.append(la.norm(r[k], ord=2) / la.norm(r[k - 1], ord=2))
  115.  
  116. if la.norm(np.matmul(A, x[k]) - b, ord=2) / la.norm(b, ord=2) < e:
  117. break
  118. return x[k], residual_norm, convergence_factor, k
  119.  
  120.  
  121. def sanity_check():
  122. A = np.array([[1, 2, -3],
  123. [2, -5, 1],
  124. [-3, 1, 5]])
  125. b = np.array([-20, -25, 70])
  126. x0 = np.array([0, 0, 0])
  127. # x = np.array([5, 10, 15])
  128. max_iter = 1000
  129. e = 10e-5
  130.  
  131. res = {1: jacobi(A, b, x0, max_iter, e)[0],
  132. 2: gauss_seidel(A, b, x0, max_iter, e)[0],
  133. 3: steepest_descent(A, b, x0, max_iter, e)[0],
  134. 4: conjugate_gradient(A, b, x0, max_iter, e)[0]
  135. }
  136. print(res)
  137.  
  138.  
  139. def plot_result(title, result, filename):
  140. residual_norm = result[1]
  141. convergence_factor = result[2]
  142. iterations = range(result[3])
  143.  
  144. fig, axs = plt.subplots(2, 1, constrained_layout=True)
  145. fig.suptitle(title, fontsize=16)
  146.  
  147. axs[0].semilogy(iterations, residual_norm)
  148. axs[0].set_title('Residual Norm')
  149. axs[0].set_xlabel('Iterations')
  150. axs[0].set_ylabel(r'$||Ax^{(k)}-b||$')
  151.  
  152. axs[1].semilogy(iterations, convergence_factor)
  153. axs[1].set_title('Convergence Factor')
  154. axs[1].set_xlabel('Iterations')
  155. axs[1].set_ylabel(r'$\frac{||Ax^{(k)}-b||}{||Ax^{(k-1)}-b||}$')
  156.  
  157. fig.savefig(f"resources/{filename}.pdf", bbox_inches='tight')
  158. plt.show(block=True)
  159.  
  160.  
  161. def q1():
  162. n = 100
  163. data = np.array([-np.ones(n), 2.1 * np.ones(n), -np.ones(n)])
  164. diags = np.array([-1, 0, 1])
  165. A = spdiags(data, diags, n, n).toarray()
  166. b = np.random.rand(n)
  167. x0 = np.zeros(n)
  168. max_iter = 100
  169. e = 1e-5
  170.  
  171. results = {
  172. "Jacobi w=1.0": jacobi(A, b, x0, max_iter, e, 1.0),
  173. "Jacobi w=0.75": jacobi(A, b, x0, max_iter, e, 0.75),
  174. "Gauss Seidel": gauss_seidel(A, b, x0, max_iter, e),
  175. "Steepest Descent": steepest_descent(A, b, x0, max_iter, e),
  176. "Conjugate Gradient": conjugate_gradient(A, b, x0, max_iter, e)
  177. }
  178.  
  179. i = 0
  180. for title, result in results.items():
  181. i += 1
  182. plot_result(title, result, f"Q1b{i}")
  183.  
  184.  
  185. def q3():
  186. A = np.array([[5, 4, 4, -1, 0],
  187. [3, 12, 4, -5, -5],
  188. [-4, 2, 6, 0, 3],
  189. [4, 5, -7, 10, 2],
  190. [1, 2, 5, 3, 10]])
  191. b = np.transpose(np.array([1, 1, 1, 1, 1]))
  192. x0 = np.transpose(np.array([0, 0, 0, 0, 0]))
  193. max_iter = 50
  194. e = 1e-5
  195.  
  196. plot_result("GMRES", GMRES(A, b, x0, max_iter, e), f"Q3c")
  197.  
  198.  
  199. def load_mnist(label1, label2):
  200. mnist = tf.contrib.learn.datasets.load_dataset("mnist")
  201. trainX = mnist.train.images
  202. trainY = np.asarray(mnist.train.labels, dtype=np.int32)
  203. testX = mnist.test.images
  204. testY = np.asarray(mnist.test.labels, dtype=np.int32)
  205.  
  206. train_idx = [idx for idx, label in enumerate(trainY) if label == label1 or label == label2]
  207. test_idx = [idx for idx, label in enumerate(testY) if label == label1 or label == label2]
  208.  
  209. trainY[trainY == label1] = -1
  210. trainY[trainY == label2] = -2
  211. trainY[trainY == -1] = 0
  212. trainY[trainY == -2] = 1
  213.  
  214. testY[testY == label1] = -1
  215. testY[testY == label2] = -2
  216. testY[testY == -1] = 0
  217. testY[testY == -2] = 1
  218.  
  219. return trainX[train_idx], trainY[train_idx], testX[test_idx], testY[test_idx]
  220.  
  221.  
  222. def sigmoid(X):
  223. return 1 / (1 + np.exp(-1 * X)) # maybe add small noise
  224.  
  225.  
  226. def cost(X, C, W):
  227. m = X.shape[1]
  228. A = sigmoid(np.matmul(X.T, W))
  229.  
  230. return (-1 / m) * (np.dot(C.T, np.log(A)) +
  231. np.dot((1 - C).T, np.log(1 - A)))
  232.  
  233.  
  234. def gradient(X, C, W):
  235. m = X.shape[1]
  236. A = sigmoid(np.matmul(X.T, W)) - C
  237. B = (1 / m) * np.dot(X, A)
  238. return B / la.norm(B, ord=2)
  239.  
  240.  
  241. def hessian(X, C, W):
  242. m = X.shape[1]
  243. A = sigmoid(np.matmul(X.T, W))
  244. D = np.diag((A * (1 - A)).reshape((-1)))
  245. return (1 / m) * np.matmul(X, np.matmul(D, X.T))
  246.  
  247.  
  248. def gradient_test(X, C, W, d, epsilon, max_iter, title, filename):
  249. f = cost(X, C, W)
  250. linear = []
  251. quadratic = []
  252.  
  253. for i in range(0, max_iter):
  254. e = epsilon ** i
  255. f_delta = cost(X + (e * d), C, W)
  256. linear.append(np.abs(f_delta - f)[0])
  257. quadratic.append(np.abs(f_delta - f - np.dot((e * d.T), gradient(X, C, W)))[0])
  258.  
  259. plt.semilogy(range(1, max_iter + 1), linear, 'r')
  260. plt.title(title + ' (linear)')
  261. plt.xlabel('Iterations')
  262. plt.ylabel(r'$|f(x + \epsilon d) - f(x)|$')
  263. plt.savefig(f"resources/{filename}_linear.pdf", bbox_inches='tight')
  264. plt.show()
  265.  
  266. plt.plot(range(1, max_iter + 1), quadratic, 'b')
  267. plt.title(title + ' (quadratic)')
  268. plt.xlabel('Iterations')
  269. plt.ylabel(r'$|f(x + \epsilon d) - f(x) - \epsilon d^T grad(x)|$')
  270. plt.savefig(f"resources/{filename}_quadratic.pdf", bbox_inches='tight')
  271. plt.show()
  272.  
  273.  
  274. def hessian_test(X, C, W, d, epsilon, max_iter, title, filename):
  275. f = cost(X, C, W)
  276. linear = []
  277. quadratic = []
  278.  
  279. for i in range(0, max_iter):
  280. e = epsilon ** i
  281. f_delta = cost(X + (e * d), C, W)
  282. linear.append(la.norm(f_delta - f))
  283. quadratic.append(la.norm(f_delta - f - np.dot((e * d.T), hessian(X, C, W))))
  284.  
  285. plt.semilogy(range(1, max_iter + 1), linear, 'r')
  286. plt.title(title + ' (linear)')
  287. plt.xlabel('Iterations')
  288. plt.ylabel(r'$||f(x + \epsilon d) - f(x)||$')
  289. plt.savefig(f"resources/{filename}_linear.pdf", bbox_inches='tight')
  290. plt.show()
  291.  
  292. plt.plot(range(1, max_iter + 1), quadratic, 'b')
  293. plt.title(title + ' (quadratic)')
  294. plt.xlabel('Iterations')
  295. plt.ylabel(r'$||f(x + \epsilon d) - f(x) - JacMV(x, \epsilon d)||$')
  296. plt.savefig(f"resources/{filename}_quadratic.pdf", bbox_inches='tight')
  297. plt.show()
  298.  
  299.  
  300. def q5b():
  301. trainX, trainY, testX, testY = load_mnist(0, 1)
  302. trainX = trainX.T
  303. testX = testX.T
  304. m = testX.shape[0]
  305. n = testX.shape[1]
  306. W = np.zeros((m, 1)) + 1e-5
  307. d = np.random.randn(m, 1)
  308. epsilon = 0.5
  309. max_iter = 30
  310.  
  311. gradient_test(testX, testY, W, d, epsilon, max_iter, "Gradient test", "Q5b1")
  312. hessian_test(testX, testY, W, d, epsilon, max_iter, "Jacobian test", "Q5b2")
  313.  
  314.  
  315. if __name__ == '__main__':
  316. plt.interactive(False)
  317. q5b()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement