Advertisement
MarLind

Til emil

Feb 20th, 2020
161
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.67 KB | None | 0 0
  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. try:
  4.     from pprint import pprint
  5. except ModuleNotFoundError:
  6.     pass
  7.  
  8. def cholesky(A):
  9.     '''
  10.    A er en positiv definitt matrise som returnerer en nedretriangulær matrise L slik at A=L L^T
  11.    '''
  12.     assert A.shape[0] == A.shape[1], "The inupt matrix is not square"
  13.     n = A.shape[0]
  14.     L = np.zeros_like(A)
  15.    
  16.     for i in range(n):
  17.         for j in range(i):
  18.             L[i, j] = (A[i, j] - np.sum(L[i,:j]*L[j,:j]) ) / L[j, j]
  19.         L[i, i] = np.sqrt(A[i, i] - np.sum(L[i,:i]**2))
  20.  
  21.     assert np.allclose(L, np.linalg.cholesky(A)), f"Cholesky failed: L:\n{L}\n" + \
  22.                                                    f"np:\n{np.linalg.cholesky(A)}\nL-np:\n{L-np.linalg.cholesky(A)}"
  23.    
  24.     # print((L@L.T - A))
  25.     # return np.linalg.cholesky(A)
  26.     return L
  27.  
  28. # ----------------------------------------------------------------
  29. #
  30. # ----------------------------------------------------------------
  31.  
  32. def substit(L,b):
  33.     '''For en nedretriangulær matrise L (nxn) og en vektor b (nx1) finn først c (nx1) slik at Lc=b
  34.    og deretter x (nx1) slik at Lx=c'''
  35.     assert (b.size == L.shape[0] == L.shape[1]) if b.ndim == 1 else True
  36.     n = b.shape[0]
  37.    
  38.     c = np.empty_like(b)
  39.    
  40.     for i in range(n):
  41.         c[i] = ( b[i] - np.sum(L[i, :i] * c[:i])) / L[i, i]
  42.    
  43.     assert np.allclose(L @ c, b), f"Forwards substitution failed:\n{L @ c - b}"
  44.    
  45.     x = np.empty_like(b)
  46.     for i in range(n-1, -1, -1):
  47.         x[i] = (c[i] - np.sum(L.T[i,i+1:]*x[i+1:])) / L[i, i]
  48.    
  49.     assert np.allclose(L.T @ x, c), f"Backwards substitution failed:\n{L.T @ x - c}"
  50.    
  51.     return x
  52.  
  53. import scipy.linalg as sclin
  54. def catch_substit(L, b, skip=False):
  55.     if not skip:
  56.         try:
  57.             substit(L, b)
  58.             return x
  59.         except AssertionError as error:
  60.             #print(error)
  61.             print("AssertionError in substit. Solving with scipy.linalg:")
  62.    
  63.     c = sclin.solve_triangular(L, b)
  64.     x = sclin.solve_triangular(L.T, c)
  65.     return x
  66.  
  67. # ----------------------------------------------------------------
  68. # Test once:
  69. # ----------------------------------------------------------------
  70.  
  71. # Verifikasjon oppgave a og b
  72. A = np.array([[1,2,3],[2,5,4],[3,4,14]])
  73. b = np.array([-2,-8,3])
  74.  
  75. # Kall dine funksjoner cholesky og substit her
  76. L = cholesky(A)
  77. x = substit(L, b)
  78.  
  79. # Skriv ut L og x, (fjern # eller modifiser flg 2 linjer)
  80. print('L=\n',L)
  81. print('x=\n',x)
  82.  
  83.  
  84.  
  85.  
  86. # ----------------------------------------------------------------
  87. # Define helper functions (given in task)
  88. # ----------------------------------------------------------------
  89.  
  90. def genM(n,Delta_t):
  91.     Delta_x = 1./(n+1)
  92.     r=Delta_t/Delta_x**2
  93.     ee=np.ones((n,))
  94.     B=(1+4*r)*np.diag(ee)-r*np.diag(ee[1:],-1)-r*np.diag(ee[1:],1)
  95.     In=np.diag(ee)
  96.     Fn=np.diag(ee[1:],1)
  97.     Gn=np.diag(ee[1:],-1)
  98.     M=np.kron(In,B)-r*np.kron(Fn,In)-r*np.kron(Gn,In)
  99.     return M
  100.  
  101.  
  102. def genU0(n):
  103.     p=n**2/4
  104.     Z0=np.zeros((n,n))
  105.     Z0[n-1,0]=p
  106.     Z0[0,n-1]=p
  107.     Z0[0,0] = p
  108.     Z0[n-1,n-1]=p
  109.     U0 = np.reshape(Z0,(n**2,1))
  110.     return U0
  111.  
  112. def surfplot(U):
  113.     from mpl_toolkits.mplot3d import Axes3D
  114.     from matplotlib import cm
  115.     n2=U.shape[0]
  116.     n=int(np.sqrt(n2))
  117.     if n2 != n**2:
  118.         print('Antall elementer i U må være et kvadrattall\n')
  119.         return
  120.     Delta_x=1/(n+1)
  121.     xx=np.linspace(Delta_x,1-Delta_x,n)
  122.     yy=np.linspace(Delta_x,1-Delta_x,n)
  123.     X,Y = np.meshgrid(xx,yy)
  124.     Z = np.reshape(U,(n,n))
  125.     fig = plt.figure()
  126.     ax = fig.gca(projection='3d')
  127.     surf = ax.plot_surface(X, Y, Z, cmap=cm.plasma,
  128.                        linewidth=1, antialiased=False)
  129.     plt.show()
  130.     return surf
  131.  
  132.  
  133.  
  134. # ----------------------------------------------------------------
  135. #
  136. # ----------------------------------------------------------------
  137.  
  138. # Her skriver du kode for å løse oppgave c
  139. #
  140. #  1. Hent U0 og beregn U1, U2, U3 ved bruk av dine cholesky- og substitfunksjoner
  141. #  2. Plott U0 og U3 med surfplot-funksjonen
  142.  
  143. n, dt = 30, 0.01
  144.  
  145. M = genM(n, dt)
  146. U_0 = genU0(n)
  147. U = [None for n in range(4)]
  148. U[0] = U_0
  149. surfplot(U[0])
  150.  
  151.  
  152. L = cholesky(M)
  153.  
  154. for i in range(len(U)-1):
  155.     U[i+1] = catch_substit(L, U[i], skip=True)
  156.  
  157.  
  158. # print(U_0)
  159. # print(U_1)
  160. surfplot(U[3])
  161.  
  162. # For å svare på Kontrollspørsmål 2, aktiver følgende
  163. Z=np.reshape(U[3],(n,n))
  164. print(Z[14,15])
  165.  
  166.  
  167. # ----------------------------------------------------------------
  168. #
  169. # ----------------------------------------------------------------
  170.  
  171.  
  172.  
  173. # ----------------------------------------------------------------
  174. #
  175. # ----------------------------------------------------------------
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement