[关闭]
@su 2014-06-26T14:46:51.000000Z 字数 13460 阅读 2758

科学计算实践上机实验报告

matlab 计算

第一次上机作业

题目

用积分方程的离散解并比较它与真解之间的误差
n=4 的复化公式求积分方程

4x3+5x22x+58(x+1)2+01(11+tx)y(t)dt=y(x)
的近似解,并在区间 [0,1] 的一些点上与真解 y(x)=1(1+x)2 进行比较

分析

代码

主函数
代码如下:

  1. %%
  2. n = 6;
  3. h = 1/n;
  4. x =0:h/2:1;
  5. a=ones(1,(2*n+1));
  6. fre = ones(1,(2*n+1));
  7. %% 这段用来定义符号变量 获得 2*n 个符号变量并存入y 以向量的方式提取
  8. cha = '[ ';
  9. for i=1:(2*n+1)
  10. cha = strcat(cha,' y',num2str(i)) ;
  11. end
  12. cha = strcat(cha,']');
  13. y = sym(cha);
  14. %%
  15. %%定义第一个函数,
  16. f1 = inline('(4*(x^3)+5*(x^2)-2*x+5)/(8*((x+1)^2))','x');
  17. %% 算出方程组每个方程的表达式
  18. solveequa = {};
  19. for i=1:2*n+1;
  20. a(i) = f1(x(i));
  21. rs= a(i)+sym(fuhuaxin(n,x(i),y))-y(i);
  22. resu = char(rs);
  23. %resul = char(y(1));
  24. res = strcat(resu,'= 0');
  25. solveequa{i} = (res );
  26. end
  27. %%求解方程并将方程的解存为向量的形式
  28. %y= solve(solveequa{1},solveequa{2},solveequa{3},solveequa{4},solveequa{5},solveequa{6},solveequa{7},solveequa{8},solveequa{9});
  29. y = solve(solveequa{:});
  30. y = struct2cell(y);
  31. yang = 1:2*n+1 ;
  32. for i=1:2*n+1;
  33. yang(i) = vpa(y{i});
  34. end
  35. %% 三次样条差值
  36. newx = 0:0.1:1;
  37. simy = interp1(x,yang,newx,'spline');
  38. %% 绘出差值的图像
  39. plot(newx,simy,'-*');
  40. hold on
  41. f3 = inline('1/((x+1)^2)','x');
  42. %% 绘出真实的函数值的图像
  43. x = 0:0.01:1;
  44. yang= x;
  45. for i = 1:101;
  46. yang(i) = f3(x(i));
  47. end
  48. plot(x,yang,'r');
  1. function[res] = fuhuaxin(n,x,y)
  2. f2 = inline('(1/(t+1)-x)*y','x','t','y');
  3. h = 1/n;
  4. t = 0:h/2:1;
  5. res = f2(x,t(1),y(1));
  6. for i=1:(n-1)
  7. res = res + 2*f2(x,t(2*i+1),y(2*i+1));
  8. end
  9. for i =1:n
  10. res = res +4* f2(x,t(2*i),y(2*i));
  11. end
  12. res = res + f2(x,t(2*n+1),y(2*n+1));
  13. res = (h/6)*res;

结果

第二次上机作业

第一题

题目

分别用共轭梯度算法和预条件共轭梯度算法求解线性方程组 Ax=b ,其中

A=411421143114411451146114711481149114101,b=58662581026409816386655382621461048577

分析

代码

主函数代码如下 GG_main:

  1. function GG_main()
  2. G = zeros(10)
  3. for t = 1:10
  4. G(t,t) = 4^t;
  5. if t>=2
  6. G(t,t-1) = 1;
  7. end
  8. if t<=9
  9. G(t,t+1) = 1;
  10. end
  11. end
  12. G
  13. b =[5 18 66 258 1026 4098 16386 65538 262146 1048577]
  14. x0 = zeros(1,10)
  15. max_iter = 1000;
  16. fprintf('\n')
  17. fprintf('Conjugate Gradient Methord:\n');
  18. fprintf('=============================');
  19. [y,iter] = cg(G, b, x0, max_iter );
  20. fprintf('\n')
  21. fprintf(' Iterative number: \n %d \n',iter);
  22. fprintf(' Solution:\n');
  23. fprintf(' %10.6f',y);
  24. fprintf('\n\n==========================\n')

cg 函数代码:

  1. function [x iter] = cg(G, b, x0, max_iter)
  2. x = x0';
  3. b=b'
  4. tolerance = 1.0e-6;
  5. fprintf('\n x0=');
  6. fprintf(' %10.6f',x0);
  7. %save sb.mat G b x
  8. r = G*x-b;
  9. d=-r;
  10. for k=1:max_iter
  11. if norm(r,2) <= tolerance
  12. iter = k-1;
  13. fprintf('\n Algorithm finds a solution!');
  14. return
  15. end
  16. alpha = (r'*r)/(d'*G*d);
  17. xx = x+alpha*d;
  18. rr = r+alpha*G*d;
  19. beta = (rr'*rr)/(r'*r);
  20. d = -rr+beta*d;
  21. x = xx;
  22. r = rr;
  23. fprintf('\n x%d = ',k);
  24. fprintf(' %10.6f',x);
  25. end
  26. iter = max_iter;
  27. return

结果

第二题

题目

用预条件共轭梯度算法求解线性方程组 Ax=b , 其中

A=BIIBIIBIIB,b=cddc
上式中 AN2×N2 维矩阵,bN2 维向量, BN×N 矩阵,IN×N 单位矩阵,c,dN 维向量,且
B=4114114114,c=2112,b=1001,N=400

分析

代码

代码主要有四个函数 main cg getmatrix getvalue 其中
1. main 为运算的入口

  1. function [] = main()
  2. %% 请输入N
  3. N = input('Please input N:');
  4. %% 通过getmatrix 函数获得矩阵
  5. [b, value, cow, row] = getmatrix(N);
  6. %% 获得向量
  7. max_it = 1000;
  8. % for m=1:N*N
  9. % for n=1:N*N
  10. % vae = getvalue(m,n,value,cow,row);
  11. % fprintf('%g\t',vae);
  12. % end
  13. % fprintf('\n')
  14. % end
  15. % disp(b);
  16. M = 1/4;
  17. x0 = zeros(N*N,1);
  18. [x, iter] = cg(b, x0,M, max_it, value, cow, row);
  19. xlswrite('test1.xlsx',x,1);
  20. iter
  21. end
  1. getmatrix 根据 N 的大小获得相应的矩阵 A 的 crs 压缩行存储格式
  1. function [b, value, cow, row]=getmatrix(N)
  2. % 这个函数的作用是产生矩阵的crs 存储 返回值是 值向量value 列向量cow 以及行向量row
  3. %% 对向量开始初始化
  4. valuelen = (N*3-2)*N + N*(N-1)*2;
  5. value = ones(valuelen,1);
  6. cow = ones(N*N,1);
  7. row = ones(valuelen,1);
  8. tempadr = 1;%利用 tempadr 记录 value 数值变化的位置;
  9. cowadr = 2;%利用 cowadr 记录 cow 列号变化的位置;
  10. rowadr = 1 ;%利用 row 记录行变化的位置
  11. %% 开始形成b
  12. c = ones(N,1);
  13. c(N) = 2;
  14. c(1) = 2;
  15. d = zeros(N,1);
  16. d(N) = 1;
  17. d(1) = 1;
  18. b = zeros(N*N,1);
  19. for t = 0:N-1
  20. temp = t*N+1;
  21. endp = (t+1)*N;
  22. if t>0 && t<N-1
  23. b(temp:endp) = d;
  24. else
  25. b(temp:endp) = c;
  26. end
  27. end
  28. %% 开始计算
  29. for t=1:N
  30. if t==1
  31. for j=1:N
  32. if j==1
  33. value(tempadr:tempadr+2) = [4 -1 -1];
  34. tempadr = tempadr + 3;
  35. cow(cowadr) = tempadr;
  36. cowadr = cowadr +1;
  37. row(rowadr:rowadr+2) =[1 2 N+1];
  38. rowadr = rowadr + 3;
  39. else
  40. if j<N
  41. value(tempadr:tempadr+3) = [-1 4 -1 -1];
  42. tempadr =tempadr + 4;
  43. cow(cowadr) = tempadr;
  44. cowadr = cowadr +1;
  45. row(rowadr:rowadr+3) =[j-1 j j+1 j+N];
  46. rowadr = rowadr + 4;
  47. else
  48. value(tempadr:tempadr+2) = [-1 4 -1];
  49. tempadr = tempadr + 3;
  50. cow(cowadr) = tempadr;
  51. cowadr = cowadr +1;
  52. row(rowadr:rowadr+2) =[j-1 j j+N];
  53. rowadr = rowadr + 3;
  54. end
  55. end
  56. end
  57. else
  58. if t<N
  59. for j=1:N
  60. if j==1
  61. value(tempadr:tempadr+3) = [-1 4 -1 -1];
  62. tempadr = tempadr + 4;
  63. cow(cowadr) = tempadr;
  64. cowadr = cowadr +1;
  65. row(rowadr:rowadr+3) =[(t-2)*N+j (t-1)*N+j (t-1)*N+j+1 t*N+j];
  66. rowadr = rowadr + 4;
  67. else
  68. if j<N
  69. value(tempadr:tempadr+4) = [-1 -1 4 -1 -1];
  70. tempadr = tempadr + 5;
  71. cow(cowadr) = tempadr;
  72. cowadr = cowadr +1;
  73. row(rowadr:rowadr+4) =[(t-2)*N+j (t-1)*N+j-1 (t-1)*N+j (t-1)*N+j+1 t*N+j];
  74. rowadr = rowadr + 5;
  75. else
  76. value(tempadr:tempadr+3) = [-1 -1 4 -1];
  77. tempadr = tempadr + 4;
  78. cow(cowadr) = tempadr;
  79. cowadr = cowadr +1;
  80. row(rowadr:rowadr+3) =[(t-2)*N+j (t-1)*N+j-1 (t-1)*N+j t*N+j];
  81. rowadr = rowadr + 4;
  82. end
  83. end
  84. end
  85. else
  86. for j=1:N
  87. if j==1
  88. value(tempadr:tempadr+2) = [-1 4 -1];
  89. tempadr = tempadr + 3;
  90. cow(cowadr) = tempadr;
  91. cowadr = cowadr +1;
  92. row(rowadr:rowadr+2) =[(t-2)*N+j (t-1)*N+j (t-1)*N+j+1 ];
  93. rowadr = rowadr + 3;
  94. else
  95. if j<N
  96. value(tempadr:tempadr+3) = [-1 -1 4 -1 ];
  97. tempadr = tempadr + 4;
  98. cow(cowadr) = tempadr;
  99. cowadr = cowadr +1;
  100. row(rowadr:rowadr+3) =[(t-2)*N+j (t-1)*N+j-1 (t-1)*N+j (t-1)*N+j+1];
  101. rowadr = rowadr + 4;
  102. else
  103. value(tempadr:tempadr+2) = [-1 -1 4 ];
  104. tempadr = tempadr + 3;
  105. cow(cowadr) = tempadr;
  106. cowadr = cowadr +1;
  107. row(rowadr:rowadr+3) =[(t-2)*N+j (t-1)*N+j-1 (t-1)*N+j (t-1)*N+j+1];
  108. rowadr = rowadr + 4;
  109. end
  110. end
  111. end
  112. end
  113. end
  114. end
  1. getvalue 根据压缩行存储格式获得矩阵相应行和列的数值(主要用来测试生成的格式是否正确)
  1. function[val] = getvalue(m,n,value,cow,row)
  2. % 这个函数通过 crs 存储的 value , cow ,row 计算出矩阵第m n列的元素的值并返回
  3. %%
  4. [lenth,~] = size(cow);
  5. if m>= lenth
  6. fprintf('Larger than the matrix\n')
  7. else
  8. val = 0;
  9. for t=cow(m):(cow(m+1)-1)
  10. if n==row(t)
  11. val = value(t);
  12. return
  13. end
  14. end
  15. end
  16. end
  1. cg 进行预优共轭梯度迭代的函数
  1. function [x, iter] = cg(b, x0,M, max_it, value, cow, row)
  2. x=x0;
  3. iter = 0;
  4. tolerance = 1.0e-6;
  5. N = length(b);
  6. %% 现在计算 A*x 的值
  7. temp= zeros(N,1);
  8. for t = 1:N
  9. for j = cow(t):(cow(t+1)-1)
  10. temp(t) = temp(t) + value(j)*x(row(j));
  11. end
  12. end
  13. r = b - temp;
  14. %% 开始循环
  15. for k=1:max_it
  16. if norm(r,2) <= tolerance*norm(b)
  17. iter = k-1;
  18. fprintf('\n Algorithm finds a solution!');
  19. return
  20. end
  21. z = M*r;
  22. iter = iter + 1;
  23. if iter==1
  24. p = z;
  25. roo = r'*z;
  26. else
  27. roos = roo;
  28. roo = r'*z;
  29. beta = roo*(1/roos);
  30. p = z + beta*p;
  31. end
  32. temp= zeros(N,1);
  33. for t = 1:N
  34. for j = cow(t):(cow(t+1)-1)
  35. temp(t) = temp(t) + value(j)*p(row(j));
  36. end
  37. end
  38. w = temp;
  39. alpha = roo*(1/(p'*w));
  40. x = x + alpha*p;
  41. r = r - alpha * w;
  42. end
  43. end

结果

第三次上机作业

第一题

题目

用差分法求解如下二阶常微分方程边值问题 (N=400)

d2udx2=x2u(0)=1,u(1)+2u(1)=1.0<x<1,

分析

代码

  1. function [] = main()
  2. %用差分法求解二阶常微分方程
  3. N = input('Please Inupt N:')
  4. stap = 0;
  5. endp = 1;
  6. h = (endp-stap)/N;
  7. xarr = stap:h:endp;
  8. %% 获得差分方程的系数矩阵
  9. A = zeros(N+1);
  10. b = ones(N+1,1);
  11. for t = 1:N+2
  12. if t==1
  13. A(t,t) = 1;
  14. b(t) = 1;
  15. else
  16. if t<=N+1
  17. A(t,t-1:t+1) = [1 -2 1];
  18. b(t) = -h*h*xarr(t)*xarr(t);
  19. else
  20. A(t,t-1:t) = [1 (1+h)/(1-h) ];
  21. b(t) = h/(1-h);
  22. end
  23. end
  24. end
  25. %% 使用追赶法求解方程组
  26. % disp(A);
  27. % disp(b);
  28. y = zeros(N+2,1);
  29. u = zeros(N+2,1);
  30. l = zeros(N+2,1);
  31. x = zeros(N+2,1);
  32. u(1) = A(1,1);
  33. y(1) = b(1);
  34. for t = 2:N+2
  35. l(t) = A(t,t-1)/u(t-1);
  36. u(t) = A(t,t) - l(t)*A(t-1,t);
  37. y(t) = b(t) - l(t)*y(t-1);
  38. end
  39. x(N+2) = y(N+2)/u(N+2);
  40. for t = N+1:-1:1;
  41. x(t) = (y(t)-A(t,t+1)*x(t+1))/u(t);
  42. end
  43. xlswrite('res.xls',x,1);
  44. plot(xarr,x(1:N+1));
  45. % disp(x);
  46. end

结果

第二题

题目

用差分法求解如下 Laplace 方程 (N=400)

{Δu=xy,u=0,(x,y)Ω=[0,1]×[0,1](x,y)Ω

分析

代码

主函数 main

  1. function [] = main()
  2. N = input('lxease Input N:');
  3. [value, cow, row, b]=getmatrix(N);
  4. % for m=1:(N+1)^2
  5. % fprintf('\n')
  6. % for n = 1:(N+1)^2
  7. % %fprintf('%f',m)
  8. % temp = getvalue(m,n,value,cow,row);
  9. % fprintf('%f\t',temp)
  10. % end
  11. % end
  12. % b;
  13. %% 使用基本迭代法求解方程组,( E+ Tx = b. then x = b-t*x
  14. res = solve_equation(value,cow,row,b);
  15. %% now plot the shape
  16. [y,x]=meshgrid(1:-1/N:0);
  17. Z =flipud( reshape(res,N+1,N+1));
  18. mesh(x,y,Z);
  19. end

getmatrix 函数 主要用来获得系数矩阵的压缩行存储格式

  1. function [value, cow, row,b] = getmatrix(N)
  2. %% 使用addm 差值节点的地址信息。
  3. [xsta, xend, ysta, yend] = deal(0, 1, 0, 1);%多变量同时赋值
  4. xh = (xend-xsta)/N;
  5. yh = (yend-ysta)/N;
  6. addm = {};
  7. for m = 1:N+1
  8. for n = 1:N+1
  9. xtemp = xsta + (m-1)*xh;
  10. ytemp = ysta + (n-1)*yh;
  11. addm(m,n) = {[xtemp, ytemp, xtemp*ytemp ],};
  12. end
  13. end
  14. %disp(addm);
  15. %% 使用crs存储方法记录系数矩阵A
  16. valuelen = (N*3-2)*N + N*(N-1)*2;
  17. value = ones(valuelen,1);
  18. cow = ones(N*N,1);
  19. row = ones(valuelen,1);
  20. tempadr = 1;%利用 tempadr 记录 value 数值变化的位置;
  21. cowadr = 1;%利用 cowadr 记录 cow 列号变化的位置;
  22. rowadr = 1 ;%利用 row 记录行变化的位置
  23. b = zeros(N*N+2*N+1,1);
  24. badr = 1;
  25. %% 从第一行开始逐个记录系数矩阵每行的
  26. for t = 1:N+1
  27. if t==1
  28. for n = 1:N+1
  29. value(tempadr) = 1;
  30. tempadr = tempadr + 1;
  31. cow(cowadr) = tempadr;
  32. cowadr = cowadr +1;
  33. row(rowadr) = (t-1)*(N-1)+n;
  34. rowadr = rowadr + 1;
  35. b(badr) = 0;
  36. badr = badr + 1;
  37. end
  38. else
  39. if t<=N
  40. value(tempadr) = 1;
  41. tempadr = tempadr + 1;
  42. cow(cowadr) = tempadr;
  43. cowadr = cowadr +1;
  44. row(rowadr) = (t-1)*(N+1)+1;
  45. rowadr = rowadr + 1;
  46. b(badr) = 0;
  47. badr = badr + 1;
  48. for n=2:N
  49. value(tempadr:tempadr+4) = [-1/4 -1/4 1 -1/4 -1/4];
  50. tempadr = tempadr +5;
  51. cow(cowadr) = tempadr;
  52. cowadr = cowadr +1;
  53. row(rowadr:rowadr+4) = [(t-2)*(N+1)+n, (t-1)*(N+1)+n-1, (t-1)*(N+1)+n, (t-1)*(N+1)+n+1, t*(N+1)+n];
  54. rowadr = rowadr + 5;
  55. b(badr) = xh*xh*addm{t,n}(3);
  56. badr = badr + 1;
  57. end
  58. value(tempadr) = 1;
  59. tempadr = tempadr + 1;
  60. cow(cowadr) = tempadr;
  61. cowadr = cowadr +1;
  62. row(rowadr) = t*(N+1);
  63. rowadr = rowadr + 1;
  64. b(badr) = 0;
  65. badr = badr + 1;
  66. else
  67. for n = 1:N+1
  68. value(tempadr) = 1;
  69. tempadr = tempadr + 1;
  70. cow(cowadr) = tempadr;
  71. cowadr = cowadr +1;
  72. row(rowadr) = (t-1)*(N+1)+n;
  73. rowadr = rowadr + 1;
  74. b(badr) = 0;
  75. badr = badr + 1;
  76. end
  77. end
  78. end
  79. end
  80. end

solve_equation 主要使用基本迭代法求解方程组

  1. function [ x ] = solve_equation( value, cow, row, b )
  2. %This function is used to solve equation
  3. %% get size of x;
  4. lenth = length(b);
  5. x0 = ones(lenth,1);
  6. x = x0;
  7. error = 1;
  8. %% 方程的解为x
  9. while error>=1e-5
  10. for m=1:lenth
  11. temp = 0;
  12. if m == 1
  13. for t = 1:(cow(m)-1)
  14. if row(t) ~= m
  15. n = row(t);
  16. temp = temp + x0(n)*value(t);
  17. end
  18. end
  19. else
  20. for t = cow(m-1):(cow(m)-1)
  21. if row(t) ~= m
  22. n = row(t);
  23. temp = temp + x0(n)*value(t);
  24. end
  25. end
  26. end
  27. temp = b(m)- temp;
  28. x(m) = temp;
  29. end
  30. error = norm(x0-x,2);
  31. x0 = x;
  32. end
  33. end

getvalue 函数 检查系数矩阵是否正确

  1. function[val] = getvalue(m,n,value,cow,row)
  2. % 这个函数通过 crs 存储的 value , cow ,row 计算出矩阵第m n列的元素的值并返回
  3. %%
  4. lenth = length(cow);
  5. if m>lenth || m<=0
  6. fprintf('Larger than the matrix')
  7. else
  8. val = 0;
  9. if m==1
  10. for t=1:(cow(m)-1)
  11. if n == row(t)
  12. val =value(t);
  13. return;
  14. end
  15. end
  16. else
  17. val = 0;
  18. for t=cow(m-1):(cow(m)-1)
  19. if n == row(t)
  20. val =value(t);
  21. return;
  22. end
  23. end
  24. end
  25. end

使用 freefem++ 通过变分法计算,代码如下:

  1. real theta=4.*pi/3;
  2. real a=2. ,b=1.;
  3. func z=0;
  4. border a0(t=0,1){x=1; y=t;}
  5. border a1(t=0,1){x=1-t;y=1;}
  6. border a2(t=0,1){x=0; y=1-t;}
  7. border a3(t=0,1){x=t;y=0;}
  8. mesh Th = buildmesh(a0(50)+a1(50)+a2(50)+a3(50));
  9. fespace Vh(Th,P2);
  10. Vh phi,w,f=x*y;
  11. solve Laplace(phi,w)=int2d(Th)(dx(phi)*dx(w) + dy(phi)*dy(w))
  12. - int2d(Th)(f*w)+on(a0,phi=z)+on(a1,phi=z)+on(a2,phi=z)+on(a3,phi=z) ;
  13. plot(phi,wait=true);
  14. plot(Th,wait=true, ps="membraneTh.eps");
  15. savemesh(Th,"trace.msh");

结果

第四次上机作业

题目

分析

代码

结果

在此输入正文

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注