当前位置:   article > 正文

数值计算/数值分析 python实践_python求解数值分析问题

python求解数值分析问题
  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. from pylab import mpl
  4. import math
  5. import random
  6. from sympy import *
  7. # 通用的基函数
  8. def LagrangeInterpolationDotN_Li(x, x_data, y_data, k):
  9. size = len(x_data)
  10. i = 0
  11. Ly = y_data[k] # 初值为Yk
  12. while( i < size):
  13. if(i != k):
  14. Ly = Ly * (x-x_data[i])/(x_data[k]-x_data[i])
  15. i += 1
  16. return (Ly)
  17. # 通用的插值函数
  18. def LagrangeInterpolationDotN_F(x, x_data, y_data):
  19. size = len(x_data)
  20. k = 0
  21. sum = 0 # 初值为0
  22. while(k < size):
  23. sum = sum + LagrangeInterpolationDotN_Li(x, x_data, y_data, k)
  24. k += 1
  25. return (sum)
  26. # 第一题需要用到的fx= 1 / (1 + x^2) 这个公式
  27. def f(x):
  28. return 1 / (1 + x ** 2)
  29. #第二题需要用的被积函数e^(2x)
  30. def f2(x):
  31. return math.exp(2*x)
  32. '''
  33. 1.1 第一题第一问:
  34. '''
  35. if __name__=="__main__":
  36. print('令插值节点为等距节点:-5、-4、-3、-2、-1、0、1、2、3、4、5,在这些节点处对 f (x)进行拉格朗日插值;')
  37. x_samples_dot11 = [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]#创建x列表存储数据x值
  38. y_samples_dot11 = [1/(1+i**2) for i in x_samples_dot11] #创建y列表存储数据的y值 这里使用了列表推导式!
  39. print("X:", x_samples_dot11)
  40. print("Y:", y_samples_dot11)
  41. x_data_predict_dot11 = np.arange(-5,5.1,0.1) # 预测点的位置
  42. y_data_predict_dot11_F = LagrangeInterpolationDotN_F (x_data_predict_dot11, x_samples_dot11, y_samples_dot11)
  43. y_data_real = [1/(1+i**2) for i in x_data_predict_dot11]
  44. error = np.abs(y_data_real - y_data_predict_dot11_F)
  45. max_error = np.max(error)
  46. print('误差值是:', max_error)
  47. plt.scatter(x_samples_dot11, y_samples_dot11, label="sample", color="black")
  48. plt.plot (x_data_predict_dot11, y_data_predict_dot11_F, label="f(x)", color="pink")
  49. mpl.rcParams['font.sans-serif'] = ['SimHei']
  50. mpl.rcParams['axes.unicode_minus'] = False
  51. plt.title("第一题第一问-拉格朗日插值拟合过程")
  52. plt.legend(loc="upper left")
  53. plt.show()
  54. '''
  55. 1.2 第一题第二问:
  56. '''
  57. if __name__=="__main__":
  58. print('令插值节点为区间[-5,5]上的 11 次切比雪夫多项式的零点,在这些节点处对 f (x)进行拉格朗日插值;')
  59. number = [1,2,3,4,5,6,7,8,9,10,11]
  60. x_samples_Chebyshev = [0 + 5*math.cos((2*i - 1)*math.pi/(2*11)) for i in number]#创建x列表存储数据x值
  61. y_samples_Chebyshev = [1/(1+i**2) for i in x_samples_Chebyshev] #创建y列表存储数据的y值 这里使用了列表推导式!
  62. print("X:", x_samples_Chebyshev)
  63. print("Y:", y_samples_Chebyshev)
  64. x_data_predict_Chebyshev = np.arange(-5,5.1,0.1) # 预测点的位置
  65. y_data_predict_Chebyshev_F = LagrangeInterpolationDotN_F (x_data_predict_Chebyshev, x_samples_Chebyshev, y_samples_Chebyshev)
  66. y_data_predict_Chebyshev_real = [1/(1+i**2) for i in x_data_predict_Chebyshev]
  67. print('误差值是:', np.max(np.abs(y_data_predict_Chebyshev_real - y_data_predict_Chebyshev_F)))
  68. plt.scatter(x_samples_Chebyshev, y_samples_Chebyshev, label="sample", color="black")
  69. plt.plot (x_data_predict_Chebyshev, y_data_predict_Chebyshev_F, label="f(x)", color="orange")
  70. mpl.rcParams['font.sans-serif'] = ['SimHei']
  71. mpl.rcParams['axes.unicode_minus'] = False
  72. plt.title("第一题第二问-拉格朗日插值拟合过程")
  73. plt.legend(loc="upper left")
  74. plt.show()
  75. '''
  76. 1.3 第一题第三问:
  77. '''
  78. if __name__=="__main__":
  79. print('令插值节点为等距节点:-5、-4、-3、-2、-1、0、1、2、3、4、5,在这些节点处对 f (x)进行分段线性插值;')
  80. x_samples_1_3 = [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]#创建x列表存储数据x值
  81. y_samples_1_3 = [1/(1+i**2) for i in x_samples_1_3]#创建y列表存储数据的y值
  82. print("X:", x_samples_1_3)
  83. print("Y:", y_samples_1_3)
  84. x_data_predict_1_3 = np.arange(-5,5.1,0.1) # 预测点的位置
  85. y_data_predict_1_3 = np.interp(x_data_predict_1_3 , x_samples_1_3, y_samples_1_3)
  86. y_data_predict_1_3_real = [1/(1+i**2) for i in x_data_predict_1_3]
  87. print('误差值是:', np.max(np.abs( y_data_predict_1_3_real - y_data_predict_1_3)))
  88. plt.scatter(x_samples_1_3, y_samples_1_3, label="sample", color="black")#画点
  89. plt.plot (x_samples_1_3, y_samples_1_3, label="sample", color="pink")#画线
  90. plt.title("第一题第三问-分段线性插值")
  91. plt.legend(loc="upper left")
  92. plt.show()
  93. '''
  94. 1.4 第一题第四问:
  95. '''
  96. print('令插值节点为等距节点:-5、-4、-3、-2、-1、0、1、2、3、4、5,在这些节点处对 f (x)进行三次样条插值:/n插值函数为 S(x) ,其中边界条件为第一类边界条件')
  97. def cal(begin, end, i):
  98. by = f(begin)
  99. ey = f(end)
  100. I = Ms[i] * ((end - n) ** 3) / 6 + Ms[i + 1] * ((n - begin) ** 3) / 6 + (by - Ms[i] / 6) * (end - n) + (
  101. ey - Ms[i + 1] / 6) * (n - begin)
  102. return I
  103. def ff(x): # f[x0, x1, ..., xk]
  104. ans = 0
  105. for i in range(len(x)):
  106. temp = 1
  107. for j in range(len(x)):
  108. if i != j:
  109. temp *= (x[i] - x[j])
  110. ans += f(x[i]) / temp
  111. return ans
  112. def calM():
  113. lam = [1] + [1 / 2] * 9
  114. miu = [1 / 2] * 9 + [1]
  115. # Y = 1 / (1 + n ** 2)
  116. # df = diff(Y, n)
  117. x = np.array(range(11)) - 5
  118. # ds = [6 * (ff(x[0:2]) - df.subs(n, x[0]))]
  119. ds = [6 * (ff(x[0:2]) - 1)]
  120. for i in range(9):
  121. ds.append(6 * ff(x[i: i + 3]))
  122. # ds.append(6 * (df.subs(n, x[10]) - ff(x[-2:])))
  123. ds.append(6 * (1 - ff(x[-2:])))
  124. Mat = np.eye(11, 11) * 2
  125. for i in range(11):
  126. if i == 0:
  127. Mat[i][1] = lam[i]
  128. elif i == 10:
  129. Mat[i][9] = miu[i - 1]
  130. else:
  131. Mat[i][i - 1] = miu[i - 1]
  132. Mat[i][i + 1] = lam[i]
  133. ds = np.mat(ds)
  134. Mat = np.mat(Mat)
  135. Ms = ds * Mat.I
  136. return Ms.tolist()[0]
  137. def calnf(x):
  138. nf = []
  139. for i in range(len(x) - 1):
  140. nf.append(cal(x[i], x[i + 1], i))
  141. return nf
  142. def calf(f, x):
  143. y = []
  144. for i in x:
  145. y.append(f.subs(n, i))
  146. return y
  147. def nfSub(x, nf):
  148. tempx = np.array(range(11)) - 5
  149. dx = []
  150. for i in range(10):
  151. labelx = []
  152. for j in range(len(x)):
  153. if x[j] >= tempx[i] and x[j] < tempx[i + 1]:
  154. labelx.append(x[j])
  155. elif i == 9 and x[j] >= tempx[i] and x[j] <= tempx[i + 1]:
  156. labelx.append(x[j])
  157. dx = dx + calf(nf[i], labelx)
  158. return np.array(dx)
  159. def draw(nf):
  160. plt.rcParams['font.sans-serif'] = ['SimHei']
  161. plt.rcParams['axes.unicode_minus'] = False
  162. x = np.linspace(-5, 5, 101)
  163. y = f(x)
  164. Ly = nfSub(x, nf)
  165. plt.plot(x, y, label='原函数')
  166. plt.plot(x, Ly, label='三次样条插值函数')
  167. plt.xlabel('x')
  168. plt.ylabel('y')
  169. plt.legend()
  170. plt.savefig('1.png')
  171. plt.show()
  172. def lossCal(nf): # 计算误差
  173. x = np.linspace(-5, 5, 101)
  174. y = f(x)
  175. Ly = nfSub(x, nf)
  176. Ly = np.array(Ly)
  177. temp = np.max(np.abs(Ly - y)) # 要求的误差
  178. print('误差值是:',temp)
  179. return temp
  180. if __name__=="__main__":
  181. x = np.array(range(11)) - 5 # 根据题意-5~5
  182. y = f(x)
  183. n, m = symbols('n m')
  184. init_printing(use_unicode=True)
  185. Ms = calM()
  186. nf = calnf(x)
  187. draw(nf)
  188. lossCal(nf)
  189. '''
  190. 1.5 第一题第五问:
  191. '''
  192. print('考虑等距节点:-5、-4、-3、-2、-1、0、1、2、3、4、5,求 f (x)在这些节点上的六次最小二乘拟合多项式,权重均为 1,')
  193. class LeastSqauresCF():
  194. def __init__(self):
  195. self.order = 1
  196. self.Xvalues = None
  197. self.Yvalues = None
  198. self.fig = plt.figure()
  199. self.subfig = self.fig.add_subplot(111)
  200. #========================================
  201. # Draw the input points/curve in a figure
  202. #========================================
  203. def ReadAnddrawInputPoints(self,Inputx=None,InputY=None, order=1):
  204. try:
  205. if Inputx is None or InputY is None:
  206. return False
  207. if(len(Inputx)!=len(InputY)):
  208. return False
  209. if order <=0:
  210. return False
  211. if type(order) !=int:
  212. self.order = int(order)
  213. else:
  214. self.order = order
  215. self.Xvalues = Inputx
  216. self.Yvalues = InputY
  217. self.subfig.plot(Inputx,InputY,color='m',linestyle='',marker='*')
  218. return True
  219. except Exception as e:
  220. print(e)
  221. return False
  222. #========================================
  223. # Calculate curve fitting factor matrix
  224. #========================================
  225. def produceFittingCurveFactors(self):
  226. try:
  227. #(1) Generate matrix [X]
  228. matX=[]
  229. for i in range(0,len(self.Xvalues)):
  230. matx1=[]
  231. for j in range(0,self.order+1):
  232. dx=1.0
  233. for l in range(0,j):
  234. dx = dx * self.Xvalues[i]
  235. matx1.append(dx)
  236. matX.append(matx1)
  237. #(2) Generate matrix [X]T.[X]
  238. matX_Trans = np.matrix(matX).T
  239. matX_FinalX = np.dot(np.matrix(matX_Trans),np.matrix(matX))
  240. #(3) Generate matrix Y' =[X]T.[Y]
  241. matFinalY = np.dot(matX_Trans,np.matrix(self.Yvalues).T)
  242. #(4) Solve the function:[A] = [[X]T.[X]]**(-1).[X]T.[Y]
  243. matAResult=np.linalg.solve(np.array(matX_FinalX),np.array(matFinalY))
  244. return matAResult
  245. except Exception as e:
  246. print(e)
  247. return None
  248. #========================================
  249. # Output fitting curve function
  250. #========================================
  251. def outputFittingCurveFunction(self, inputMatFactors=None):
  252. if inputMatFactors is None:
  253. return False
  254. i = 0
  255. strFitting="Function(x)="
  256. for a in inputMatFactors:
  257. #print(a[0])
  258. if i==0:
  259. strFitting +=str(a[0])
  260. else:
  261. strFitting +=("+"if a[0]>0 else"") +str(a[0])+(("x**"+str(i)) if i>1 else "x")
  262. i+=1
  263. print(strFitting)
  264. return strFitting
  265. #========================================
  266. # draw the curve based on the result function
  267. #========================================
  268. def drawFittedCurve(self, xRangeMin=None,xRangeMax=None,matAResult=None,resolution=0.01):
  269. try:
  270. if matAResult is None:
  271. return False
  272. if xRangeMin is None or xRangeMax is None:
  273. xRangeMin = self.Xvalues[0]
  274. xRangeMax = self.Xvalues[-1]
  275. #print('xRangeMin: ',xRangeMin, 'xRangeMax: ',xRangeMax)
  276. xxa= np.arange(xRangeMin,xRangeMax,resolution)
  277. yya=[]
  278. for i in range(0,len(xxa)):
  279. yy=0.0
  280. for j in range(0,self.order+1):
  281. dy=1.0
  282. #x[i]**j
  283. for k in range(0,j):
  284. dy*=xxa[i]
  285. #a[j]*(x[i]**j)
  286. dy*=matAResult[j]
  287. yy+=dy
  288. yya.append(yy)
  289. #print(xxa,yya)
  290. self.subfig.plot(xxa,yya,color='g',linestyle='-',marker='')
  291. plt.show()
  292. return True
  293. except Exception as e:
  294. print(e)
  295. return False
  296. def calculateAbsoluteError(self, matAResult):
  297. try:
  298. yFitted = []
  299. for x in self.Xvalues:
  300. y = 0.0
  301. for i, a in enumerate(matAResult):
  302. y += a * (x ** i)
  303. yFitted.append(y)
  304. absoluteError = np.abs(np.array(self.Yvalues) - np.array(yFitted))
  305. meanAbsoluteError = np.mean(absoluteError)
  306. return meanAbsoluteError
  307. except Exception as e:
  308. print(e)
  309. return None
  310. if __name__=="__main__":
  311. LS = LeastSqauresCF()
  312. sorted_x = [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]
  313. sorted_y = [1/(1+i**2) for i in x_samples_dot11]
  314. if LS.ReadAnddrawInputPoints(sorted_x,sorted_y,6):
  315. MatrixFactor = LS.produceFittingCurveFactors()
  316. LS.outputFittingCurveFunction(MatrixFactor)
  317. LS.drawFittedCurve(matAResult=MatrixFactor)
  318. print("误差值是:",LS.calculateAbsoluteError(MatrixFactor))
  319. '''
  320. 2.1 第二题第一问:
  321. '''
  322. print('将区间[3,5]等分 40 份,用复合梯形公式计算:')
  323. def trapezoid(a, b, n): # 复合梯形公式
  324. h=(b-a)/n
  325. x=a
  326. s=f2(x)-f2(b)
  327. for k in range(1,n+1):
  328. x=x+h
  329. s=s+2*f2(x)
  330. result=(h/2)*s
  331. return result
  332. def simpson(a,b,n): # 辛普森公式
  333. h=(b-a)/n
  334. x=a
  335. s=f2(x)-f2(b)
  336. for k in range(1,n+1):
  337. x=x+h/2
  338. s=s+4*f2(x)
  339. x=x+h/2
  340. s=s+2*f2(x)
  341. result=(h/6)*s
  342. return result
  343. if __name__=="__main__":
  344. print('S=',trapezoid(3,5,40))
  345. '''
  346. 2.2 第二题第二问:
  347. '''
  348. print('将区间[3,5]等分 20 份,用复合辛普森公式计算(每个小区间需加中点):')
  349. if __name__=="__main__":
  350. print('S=',simpson(3,5,40))
  351. '''
  352. 2.3 第二题第三问:
  353. '''
  354. print('T0将区间[3,5]等分为 20 份的复合梯形公式,用龙贝格积分算法加速一次,算出T1:')
  355. import math
  356. def romberg_integration(a, b, n, num_iterations,f):
  357. results = [[0] * (num_iterations+1) for _ in range(num_iterations+1)]
  358. h = (b - a) / n
  359. x = [a + i * h for i in range(n+1)]
  360. sum_value = sum([f(x[i]) for i in range(1, n)])
  361. results[0][0] = h * (0.5 * (f(a) + f(b)) + sum_value)
  362. for i in range(1, num_iterations+1):
  363. h *= 0.5
  364. sum_value = sum([f(x[j]) for j in range(1, 2**(i-1)+1, 2)])
  365. results[i][0] = 0.5 * results[i-1][0] + h * sum_value
  366. for j in range(1, i+1):
  367. results[i][j] = results[i][j-1] + (results[i][j-1] - results[i-1][j-1]) / ((4**j) - 1)
  368. return results[num_iterations][num_iterations]
  369. if __name__=="__main__":
  370. # 使用龙贝格积分算法加速一次
  371. T1_h_romberg = romberg_integration(3, 5, 20, 1, f2)
  372. print("T1(h) (with Romberg acceleration) =", T1_h_romberg)
  373. '''
  374. 2.4 第二题第四问:
  375. '''
  376. print('将区间[3,5]等分为 10 份的复合梯形公式,用龙贝格积分算法加速两次,算出T2:')
  377. if __name__=="__main__":
  378. T2_h_romberg = romberg_integration(3, 5, 10, 2, f2)
  379. print("T2(h) (with Romberg acceleration) =", T2_h_romberg)
  380. '''
  381. 2.5 第二题第五问:
  382. '''
  383. print('将区间[3,5]等分为 5 份的复合梯形公式,用龙贝格积分算法加速三次,算出32:')
  384. if __name__=="__main__":
  385. T3_h_romberg = romberg_integration(3, 5, 5, 3, f2)
  386. print("T3(h) (with Romberg acceleration) =", T3_h_romberg)
  387. '''
  388. 2.6 第二题第六问:
  389. '''
  390. print('将区间[3,5]等分 20 份,用复合的 2 点高斯公式计算:')
  391. def composite_gauss2(f, a, b, n):
  392. # 复合的2点高斯公式计算积分 书上有结论~
  393. integral = 0
  394. nodes = np.linspace(a, b, n+1)
  395. for i in range(n):
  396. x1 = nodes[i]
  397. x2 = nodes[i+1]
  398. mid_point = 0.5 * (x1 + x2)
  399. width = 0.5 * (x2 - x1)
  400. # 计算节点上的权重和函数值
  401. weight1 = 1 # A0=A1=1 X0 X1是正负跟号3
  402. weight2 = 1
  403. function_value1 = f(0.5 * width * (-1/np.sqrt(3)) + mid_point) # 平移到子区间
  404. function_value2 = f(0.5 * width * (1/np.sqrt(3)) + mid_point)
  405. # 计算积分部分并累加
  406. integral += width * (weight1 * function_value1 + weight2 * function_value2)
  407. return integral
  408. # 将区间[3, 5]等分为20份,计算积分
  409. integral01 = composite_gauss2(f2, 3, 5, 20)
  410. print("Integral:", integral01)
  411. '''
  412. 2.7 第二题第七问:
  413. '''
  414. print('将区间[3,5]等分 10 份,用复合的 4 点高斯公式计算:')
  415. def composite_gauss4(f, a, b, n):
  416. # 复合的四点高斯公式计算积分
  417. integral = 0
  418. nodes = np.linspace(a, b, n+1)
  419. for i in range(n):
  420. x1 = nodes[i]
  421. x2 = nodes[i+1]
  422. h = x2 - x1
  423. # 四个节点的位置
  424. t1 = -np.sqrt((3 + 2*np.sqrt(6/5))/7)
  425. t2 = -np.sqrt((3 - 2*np.sqrt(6/5))/7)
  426. t3 = np.sqrt((3 - 2*np.sqrt(6/5))/7)
  427. t4 = np.sqrt((3 + 2*np.sqrt(6/5))/7)
  428. # 四个节点的权重
  429. w1 = (18 - np.sqrt(30))/36
  430. w2 = (18 + np.sqrt(30))/36
  431. w3 = (18 + np.sqrt(30))/36
  432. w4 = (18 - np.sqrt(30))/36
  433. # 计算积分部分并累加
  434. integral += 0.5 * h * (w1 * f(0.5 * h * t1 + 0.5 * (x1 + x2)) +
  435. w2 * f(0.5 * h * t2 + 0.5 * (x1 + x2)) +
  436. w3 * f(0.5 * h * t3 + 0.5 * (x1 + x2)) +
  437. w4 * f(0.5 * h * t4 + 0.5 * (x1 + x2)))
  438. return integral
  439. # 将区间[3, 5]等分为20份,计算积分
  440. integral02 = composite_gauss4(f2, 3, 5, 10)
  441. print("Integral:", integral02)
  442. '''
  443. 3 第三题:
  444. '''
  445. A = np.array([[3, 1, 1], [1, 3, 1], [1, 1, 3]])
  446. b = np.array([3, 0, 2])
  447. x0 = np.zeros_like(b) # 初始猜测解 全0
  448. max_iterations = 100 # 最大迭代次数
  449. tolerance = 1e-8 # 允许误差
  450. # 使用numpy.linalg.solve()函数求解线性方程组
  451. solution_true = np.linalg.solve(A, b)
  452. print("正确的解为", solution_true)
  453. print('雅可比迭代法:')
  454. def DLU(A):
  455. D=np.zeros(np.shape(A))
  456. L=np.zeros(np.shape(A))
  457. U=np.zeros(np.shape(A))
  458. for i in range(A.shape[0]):
  459. D[i,i]=A[i,i]
  460. for j in range(i):
  461. L[i,j]=-A[i,j]
  462. for k in list(range(i+1,A.shape[1])):
  463. U[i,k]=-A[i,k]
  464. L=np.mat(L)
  465. D=np.mat(D)
  466. U=np.mat(U)
  467. return D,L,U
  468. #迭代
  469. def Jacobi_iterative(A,b,x0,maxN,p): #x0为初始值,maxN为最大迭代次数,p为允许误差
  470. D,L,U=DLU(A)
  471. if len(A)==len(b):
  472. D_inv=np.linalg.inv(D)
  473. D_inv=np.mat(D_inv)
  474. B=D_inv * (L+U)
  475. B=np.mat(B)
  476. f=D_inv*b
  477. f=np.mat(f)
  478. else:
  479. print('维数不一致')
  480. sys.exit(0) # 强制退出
  481. a,b=np.linalg.eig(B) #a为特征值集合,b为特征值向量
  482. c=np.max(np.abs(a)) #返回谱半径
  483. if c<1:
  484. print('迭代收敛')
  485. else:
  486. print('迭代不收敛')
  487. sys.exit(0) # 强制退出
  488. #以上都是判断迭代能否进行的过程,下面正式迭代
  489. k=0
  490. while k<maxN:
  491. x=B*x0+f
  492. k=k+1
  493. eps=np.linalg.norm(x-x0,ord=2)
  494. if eps<p:
  495. break
  496. else:
  497. x0=x
  498. return k,x
  499. A1 = np.mat([[3, 1, 1], [1, 3, 1], [1, 1, 3]])
  500. b1 = np.mat([[3],[0],[2]])
  501. x01=np.mat([[0],[0],[0]])
  502. k,solution_jacobi=Jacobi_iterative(A1,b1,x01,max_iterations,tolerance)
  503. print("迭代次数:",k)
  504. residual = A1.dot(solution_jacobi) - b1
  505. residual_norm = np.linalg.norm(residual, ord=np.inf)
  506. print("残差:", residual_norm)
  507. print("Solution:", solution_jacobi)
  508. print('高斯赛德尔迭代法')
  509. def Guss_Selbi(a, b, x, g): # a为系数矩阵 b增广的一列 x迭代初始值 g计算精度
  510. x = x.astype(float) # 设置x的精度,让x计算中能显示多位小数
  511. m, n = a.shape
  512. times = 0 # 迭代次数
  513. if (m < n):
  514. print("There is a 解空间。") # 保证方程个数大于未知数个数
  515. else:
  516. while True:
  517. for i in range(n):
  518. s1 = 0
  519. tempx = x.copy() # 记录上一次的迭代答案
  520. for j in range(n):
  521. if i != j:
  522. s1 += x[j] * a[i][j]
  523. x[i] = (b[i] - s1) / a[i][i]
  524. times += 1 # 迭代次数加一
  525. gap = max(abs(x - tempx)) # 与上一次答案模的差
  526. if gap < g: # 精度满足要求,结束
  527. break
  528. elif times > 10000: # 如果迭代超过10000次,结束
  529. break
  530. print("10000次迭代仍不收敛")
  531. print('迭代次数:',times)
  532. return x
  533. solution_gauss = Guss_Selbi(A, b, x0, tolerance)
  534. print("残差:", np.linalg.norm(solution_true - solution_gauss, ord=np.inf))
  535. print("Solution:", solution_gauss)
  536. print('超松弛迭代法:')
  537. def sor_iteration(A,b,X0,max1, tolerance, w):
  538. '''A代表线性方程组AX=b的系数矩阵
  539. b代表线性方程组AX=b右边的部分
  540. X0代表高斯—赛德尔迭代的初始值
  541. w代表松弛因子
  542. max1代表迭代的次数'''
  543. n=np.shape(A)[0]
  544. L=-np.tril(A,-1)
  545. U=-np.triu(A,1)
  546. D=A+L+U
  547. B=np.dot(np.linalg.inv(D-w*L),((1-w)*D+w*U))
  548. f=np.dot(np.linalg.inv(D-w*L),w*b)
  549. err = np.inf
  550. for i in range(max1) :
  551. if err <= tolerance:
  552. break
  553. X0=np.dot(B,X0)+f
  554. err=np.linalg.norm(np.dot(A,X0)-b,ord=2)
  555. print("迭代次数:", i)
  556. return X0
  557. omega = 6 / (3 + math.sqrt(5))
  558. solution_sor = sor_iteration(A, b, x0, max_iterations, tolerance, omega)
  559. print("残差:", np.linalg.norm(solution_true - solution_sor, ord=np.inf))
  560. print("Solution:", solution_sor)
  561. print('最速梯度下降法:')
  562. def steepest_descent_linear_system(A, b, initial_x, max_iterations, tolerance):
  563. x = initial_x
  564. iteration = 0
  565. error = np.inf
  566. while iteration < max_iterations and error > tolerance:
  567. Ax = np.dot(A, x)
  568. residual = Ax - b
  569. gradient = np.dot(A.T, residual)
  570. alpha = np.dot(residual, residual) / np.dot(np.dot(A, residual), residual)
  571. x_new = x - alpha * residual
  572. error = np.linalg.norm(x_new - x)
  573. x = x_new
  574. iteration += 1
  575. print('迭代次数:', iteration)
  576. return x
  577. solution_sdls = steepest_descent_linear_system(A, b, x0, max_iterations, tolerance)
  578. print("残差:", np.linalg.norm(solution_true - solution_sdls, ord=np.inf))
  579. print("Solution:", solution_sdls)
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小桥流水78/article/detail/995542
推荐阅读
相关标签
  

闽ICP备14008679号