文章目录
1 数学理论
1.1 问题
1.2 问题解答
2 程序
3 结果分析说明
3.1 初步验证迭代程序的正确性
3.2 解答题目内容
3.2.1 比较三种迭代法的次数
3.2.2 差分解与精确解的精度
4 遇到的问题与解决
附录
1 数学理论.
1.1 问题
1.2 问题解答
2 程序.
见附录
3 结果分析说明
3.1 初步验证迭代程序的正确性
- 取 h = k = 1/2, 1/4, 1/8,验证各个迭代法是否随着区间划分的增多,然后近似解与精确解的误差减小,结果如下:
- 结果分析:由上面的图表可以知道,随着分点数的增加,误差是减小的,也就是说所给程序,初步验证是可以和理论相结合的。
3.2 解答题目内容.
3.2.1 比较三种迭代法的次数
- h= k= 1/ 64
结果分析:在 h= k= 1/64 时,Jacobi 方法的迭代次数是 7811 次,SOR 方法的迭代次数是 192 次,Gauss-Seidel 方法的迭代次数是 4211 次。由理论上可以知道 Gauss-Seidel 方法的迭代速度为 Jacobi 方法迭代次数的两倍,而选择恰当的松弛因子时,SOR 可以大大的加快迭代速度。从实验结果来看,无疑是证明了理论的正确性。 - h= k= 1/128
结果分析:在 h= k= 1/64 时,Jacobi 方法的迭代次数是 28951 次,SOR 方法的迭代次数是 383 次,Gauss-Seidel 方法的迭代次数是 15660 次。由理论上可以知道 Gauss-Seidel 方法的迭代速度为 Jacobi 方法迭代次数的两倍,而选择恰当的松弛因子时,SOR 可以大大的加快迭代速度。从实验结果来看,无疑是证明了理论的正确性。 - 两种步长的比较
从比较结果来看,随着步长的减小,迭代次数明显增加。
3.2.2 差分解与精确解的精度
- h= k= 1/64
这里求出了误差矩阵的分布
结果分析:这里由误差矩阵的分布来看,各个迭代方法的误差矩阵的分布是相似的,很难比较出结果。为了简单起见,求出各个误差矩阵的最大值,利用最大值来比较,整理出结果如下图。可以知道max误差最大的是 Jacobi 迭代法 ,为 0.9374。其次是 Gauss-Seidel,为 0.8974。最后max误差最小为 SOR 法,为 0.8588。从实验结果来看,这也验证了理论上,当选取合适的迭代松弛因子时,SOR 的精度较高,而 Gauss-Seidel 次之,Jacobi 最小。
- h= k= 1/128
这里求出了误差矩阵的分布
结果分析:这里由误差矩阵的分布来看,各个迭代方法的误差矩阵的分布是相似的,很难比较出结果。为了简单起见,求出各个误差矩阵的最大值,利用最大值来比较,整理出结果如下图。可以知道max误差最大的是 Jacobi 迭代法 ,为 0.7517。其次是 Gauss-Seidel,为 0.5887。最后max误差最小为 SOR 法,为 0.4303。从实验结果来看,这也验证了理论上,当选取合适的迭代松弛因子时,SOR 的精度较高,而 Gauss-Seidel 次之,Jacobi 最小。
- 两种步长的比较
从下图结果可以知道,当减小步长时,各个迭代法的最大误差也是减小的
4 遇到的问题与解决.
- 对于公式的不理解,通过反复向老师请教,得到了相对正确的理解,非常感谢老师的指导和帮助。
- 对数据和分析不够,比如对误差矩阵的分布,如果能够动态的展示不同迭代方法的误差分布,以及不同步长的误差分布,那么可以有效的利用误差分布来进行问题的分析,在本文中仅仅利用最大误差说服力是不够的
- 对下面题目的理解
第一行是一个差分方程,左边是一个拉普拉斯算子,右边可以称之为右端函数。当右端函数为零,即 Δu = 0 时,那么,这个差分方程称为 拉普拉斯方程;当右端函数不为零时,这个差分方程称为 泊松方程。
在本题中注意一点,标准的拉普拉斯方程是 -Δu = 0 ,本题中 泊松方程对应的标准方程应该为 Δu = -f。我对问题的解答时,也就是进行数学迭代公式的演算时,并未将拉普拉斯方程化为标准型来计算。
这里有点儿绕哈,相差一个负号,会导致不同的结果。不过在程序运行时,通过观察变量的结果可以很容易看出自己是否符号搞反了。 - 高斯塞德尔迭代法这里比较难理解
因为 高斯塞德尔法提前生成了点,所以下面这样写程序是正确的
附录.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 | 1,main 函数 % %% 主函数 clc; clear; matrixH = [1/64]; errorArray=[]; % 和精确解比较,观察随着 h 的减小,error 是否减小 for iterator = 1: length(matrixH) h = matrixH(iterator); %h = 1/ 64; % 步长 % h = 1/ 128; n = 1/ h; % 矩阵最大维度 e = 0.0001; % 精度,重合到小数点后四位 maxIterator = 100000; right_value = Right(h, n, e); % 精确解 [ja_value, timesJacobi,errorJacobi, errorRightJacobi] = Jacobi(h, n, e,right_value, maxIterator); % 雅可比 [sor_value, timesSOR,errorSOR, errorRightSOR] = SOR(h, n, e,right_value,maxIterator); % 逐次超松弛 [gauss_value, timesGauss,errorGauss, errorRightGauss] = GaussSider(h, n, e,right_value,maxIterator); % 高斯赛德尔 errorArrayGauss(iterator) = errorGauss; errorArrayJacobi(iterator) = errorJacobi; errorArraySOR(iterator) = errorSOR; end %% 画图 plotResult(1, 'Gauss', matrixH, errorArrayGauss, errorRightGauss); plotResult(2, 'Jacobi',matrixH, errorArrayJacobi, errorRightJacobi); plotResult(3, 'SOR', matrixH, errorArraySOR, errorRightSOR); figure(4) times = [timesJacobi, timesSOR, timesGauss]; bar(times); xlabel('名称'); ylabel('迭代总次数'); title('Jacobi, SOR, Gauss 的迭代次数对比'); set(gca, 'XTickLabel', {'Jacobi', 'SOR', 'Gauss'}); for i= 1: length(times) str = sprintf('%d', times(i)); text(i-0.1, times(i)+3,str); end 2,绘图函数 %% 绘图函数 function result = plotResult(figureNum, name, matrixH, errorArray, errorRight) figure(figureNum); subplot(2,2,1); plot(fliplr(matrixH), errorArray); xlabel('h'); ylabel('errorNorm_2'); title(strcat(name, ': 随着分点数的增加,即 h 的减小,error矩阵的二范数减小')); box off; subplot(2,2,2); x = 0: matrixH(length(matrixH)): 1; y = 0: matrixH(length(matrixH)): 1; plotArray = errorRight.^2; %plotArrayGauss = sqrt(plotArrayGauss); surf(x, y, plotArray(:,:)); xlabel('x'); ylabel('y'); zlabel('z'); title(strcat(name, ': 精确解和近似解相减后得到的平方')); box off; end 3,高斯函数 %% 高斯赛德尔函数 function [r, times, error,errorRight] = GaussSider(h, n, e,right_value,maxIterator) u = zeros(n+1, n+1); % 初边值条件简写 old = zeros(n+1, n+1); x = zeros(n); y = zeros(n); for i = 2: n x(i) = (i-1)*h; end for j = 2: n y(j) = (j-1)*h; end k = 1; while(true) for i = 2:n for j = 2:n a1 = u(i+1, j); a2 = u(i-1, j); a3 = u(i, j+1); a4 = u(i, j-1); u(i, j) = (1/4)*(-h*h*f_u(x(i), y(j)) + a1 + a2 + a3 + a4); end end errorArray(k) = norm((u-old),2); if(errorArray(k)<e||k>maxIterator) break; else old = u; k = k+1; end end errorRight = u-right_value; error = norm(errorRight, 2); times = k; r = u; end 4,雅可比函数 %% 雅可比函数,很难,要实现与节点编排顺序无关 function [r,times,error, errorRight] = Jacobi(h, n, e,right_value,maxIterator) u = zeros(n+1, n+1); % 初边值条件简写 old = zeros(n+1, n+1); % 上一次迭代情况 k = 1; x = zeros(n); y = zeros(n); for i = 2: n x(i) = (i-1)*h; for j = 2: n y(j) = (j-1)*h; end end while(true) for i = 2:n for j = 2:n a1 = old(i+1, j); a2 = old(i-1, j); a3 = old(i, j+1); a4 = old(i, j-1); u(i, j) = (1/4)*(-h*h*f_u(x(i), y(j)) + a1 + a2 + a3 + a4); end end errorArray(k) = norm((u-old),2); if(errorArray(k)<e || k >maxIterator) break; else old = u; k = k+1; end end errorRight = u-right_value; error = norm(errorRight, 2); times = k; r = u; end 5,SOR 函数 %% 雅可比函数,很难,要实现与节点编排顺序无关 function [r,times,error, errorRight] = Jacobi(h, n, e,right_value,maxIterator) u = zeros(n+1, n+1); % 初边值条件简写 old = zeros(n+1, n+1); % 上一次迭代情况 k = 1; x = zeros(n); y = zeros(n); for i = 2: n x(i) = (i-1)*h; for j = 2: n y(j) = (j-1)*h; end end while(true) for i = 2:n for j = 2:n a1 = old(i+1, j); a2 = old(i-1, j); a3 = old(i, j+1); a4 = old(i, j-1); u(i, j) = (1/4)*(-h*h*f_u(x(i), y(j)) + a1 + a2 + a3 + a4); end end errorArray(k) = norm((u-old),2); if(errorArray(k)<e || k >maxIterator) break; else old = u; k = k+1; end end errorRight = u-right_value; error = norm(errorRight, 2); times = k; r = u; end 6,求解精确解 %% 精确解 function r = Right(h, n, e) u = zeros(n+1, n+1); % 初边值条件简写 for i=2: n for j=2: n x = (i-1)*h; y = (j-1)*h; u(i,j)= f_R(x, y); end end r = u; end 7,右端函数 %% fij 函数 function r = f_u(x, y) r1 = 2*pi*pi*exp(pi*(x+y)); r2 = sin(pi*x)*cos(pi*y) + cos(pi*x)*sin(pi*y); r = r1 * r2; end 8,精确解函数 %% 精确解函数 function r = f_R(x, y) r = exp(pi*(x+y))*sin(pi*x)*sin(pi*y); end |