@su
2014-06-26T14:46:51.000000Z
字数 13460
阅读 2758
matlab 计算
用积分方程的离散解并比较它与真解之间的误差
用
主函数
代码如下:
%%n = 6;h = 1/n;x =0:h/2:1;a=ones(1,(2*n+1));fre = ones(1,(2*n+1));%% 这段用来定义符号变量 获得 2*n 个符号变量并存入y 以向量的方式提取cha = '[ ';for i=1:(2*n+1)cha = strcat(cha,' y',num2str(i)) ;endcha = strcat(cha,']');y = sym(cha);%%%%定义第一个函数,f1 = inline('(4*(x^3)+5*(x^2)-2*x+5)/(8*((x+1)^2))','x');%% 算出方程组每个方程的表达式solveequa = {};for i=1:2*n+1;a(i) = f1(x(i));rs= a(i)+sym(fuhuaxin(n,x(i),y))-y(i);resu = char(rs);%resul = char(y(1));res = strcat(resu,'= 0');solveequa{i} = (res );end%%求解方程并将方程的解存为向量的形式%y= solve(solveequa{1},solveequa{2},solveequa{3},solveequa{4},solveequa{5},solveequa{6},solveequa{7},solveequa{8},solveequa{9});y = solve(solveequa{:});y = struct2cell(y);yang = 1:2*n+1 ;for i=1:2*n+1;yang(i) = vpa(y{i});end%% 三次样条差值newx = 0:0.1:1;simy = interp1(x,yang,newx,'spline');%% 绘出差值的图像plot(newx,simy,'-*');hold onf3 = inline('1/((x+1)^2)','x');%% 绘出真实的函数值的图像x = 0:0.01:1;yang= x;for i = 1:101;yang(i) = f3(x(i));endplot(x,yang,'r');
function[res] = fuhuaxin(n,x,y)f2 = inline('(1/(t+1)-x)*y','x','t','y');h = 1/n;t = 0:h/2:1;res = f2(x,t(1),y(1));for i=1:(n-1)res = res + 2*f2(x,t(2*i+1),y(2*i+1));endfor i =1:nres = res +4* f2(x,t(2*i),y(2*i));endres = res + f2(x,t(2*n+1),y(2*n+1));res = (h/6)*res;

分别用共轭梯度算法和预条件共轭梯度算法求解线性方程组
主函数代码如下 GG_main:
function GG_main()G = zeros(10)for t = 1:10G(t,t) = 4^t;if t>=2G(t,t-1) = 1;endif t<=9G(t,t+1) = 1;endendGb =[5 18 66 258 1026 4098 16386 65538 262146 1048577]x0 = zeros(1,10)max_iter = 1000;fprintf('\n')fprintf('Conjugate Gradient Methord:\n');fprintf('=============================');[y,iter] = cg(G, b, x0, max_iter );fprintf('\n')fprintf(' Iterative number: \n %d \n',iter);fprintf(' Solution:\n');fprintf(' %10.6f',y);fprintf('\n\n==========================\n')
cg 函数代码:
function [x iter] = cg(G, b, x0, max_iter)x = x0';b=b'tolerance = 1.0e-6;fprintf('\n x0=');fprintf(' %10.6f',x0);%save sb.mat G b xr = G*x-b;d=-r;for k=1:max_iterif norm(r,2) <= toleranceiter = k-1;fprintf('\n Algorithm finds a solution!');returnendalpha = (r'*r)/(d'*G*d);xx = x+alpha*d;rr = r+alpha*G*d;beta = (rr'*rr)/(r'*r);d = -rr+beta*d;x = xx;r = rr;fprintf('\n x%d = ',k);fprintf(' %10.6f',x);enditer = max_iter;return


用预条件共轭梯度算法求解线性方程组
代码主要有四个函数 main cg getmatrix getvalue 其中
1. main 为运算的入口;
function [] = main()%% 请输入NN = input('Please input N:');%% 通过getmatrix 函数获得矩阵[b, value, cow, row] = getmatrix(N);%% 获得向量max_it = 1000;% for m=1:N*N% for n=1:N*N% vae = getvalue(m,n,value,cow,row);% fprintf('%g\t',vae);% end% fprintf('\n')% end% disp(b);M = 1/4;x0 = zeros(N*N,1);[x, iter] = cg(b, x0,M, max_it, value, cow, row);xlswrite('test1.xlsx',x,1);iterend
function [b, value, cow, row]=getmatrix(N)% 这个函数的作用是产生矩阵的crs 存储 返回值是 值向量value, 列向量cow 以及行向量row。%% 对向量开始初始化valuelen = (N*3-2)*N + N*(N-1)*2;value = ones(valuelen,1);cow = ones(N*N,1);row = ones(valuelen,1);tempadr = 1;%利用 tempadr 记录 value 数值变化的位置;cowadr = 2;%利用 cowadr 记录 cow 列号变化的位置;rowadr = 1 ;%利用 row 记录行变化的位置%% 开始形成bc = ones(N,1);c(N) = 2;c(1) = 2;d = zeros(N,1);d(N) = 1;d(1) = 1;b = zeros(N*N,1);for t = 0:N-1temp = t*N+1;endp = (t+1)*N;if t>0 && t<N-1b(temp:endp) = d;elseb(temp:endp) = c;endend%% 开始计算for t=1:Nif t==1for j=1:Nif j==1value(tempadr:tempadr+2) = [4 -1 -1];tempadr = tempadr + 3;cow(cowadr) = tempadr;cowadr = cowadr +1;row(rowadr:rowadr+2) =[1 2 N+1];rowadr = rowadr + 3;elseif j<Nvalue(tempadr:tempadr+3) = [-1 4 -1 -1];tempadr =tempadr + 4;cow(cowadr) = tempadr;cowadr = cowadr +1;row(rowadr:rowadr+3) =[j-1 j j+1 j+N];rowadr = rowadr + 4;elsevalue(tempadr:tempadr+2) = [-1 4 -1];tempadr = tempadr + 3;cow(cowadr) = tempadr;cowadr = cowadr +1;row(rowadr:rowadr+2) =[j-1 j j+N];rowadr = rowadr + 3;endendendelseif t<Nfor j=1:Nif j==1value(tempadr:tempadr+3) = [-1 4 -1 -1];tempadr = tempadr + 4;cow(cowadr) = tempadr;cowadr = cowadr +1;row(rowadr:rowadr+3) =[(t-2)*N+j (t-1)*N+j (t-1)*N+j+1 t*N+j];rowadr = rowadr + 4;elseif j<Nvalue(tempadr:tempadr+4) = [-1 -1 4 -1 -1];tempadr = tempadr + 5;cow(cowadr) = tempadr;cowadr = cowadr +1;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];rowadr = rowadr + 5;elsevalue(tempadr:tempadr+3) = [-1 -1 4 -1];tempadr = tempadr + 4;cow(cowadr) = tempadr;cowadr = cowadr +1;row(rowadr:rowadr+3) =[(t-2)*N+j (t-1)*N+j-1 (t-1)*N+j t*N+j];rowadr = rowadr + 4;endendendelsefor j=1:Nif j==1value(tempadr:tempadr+2) = [-1 4 -1];tempadr = tempadr + 3;cow(cowadr) = tempadr;cowadr = cowadr +1;row(rowadr:rowadr+2) =[(t-2)*N+j (t-1)*N+j (t-1)*N+j+1 ];rowadr = rowadr + 3;elseif j<Nvalue(tempadr:tempadr+3) = [-1 -1 4 -1 ];tempadr = tempadr + 4;cow(cowadr) = tempadr;cowadr = cowadr +1;row(rowadr:rowadr+3) =[(t-2)*N+j (t-1)*N+j-1 (t-1)*N+j (t-1)*N+j+1];rowadr = rowadr + 4;elsevalue(tempadr:tempadr+2) = [-1 -1 4 ];tempadr = tempadr + 3;cow(cowadr) = tempadr;cowadr = cowadr +1;row(rowadr:rowadr+3) =[(t-2)*N+j (t-1)*N+j-1 (t-1)*N+j (t-1)*N+j+1];rowadr = rowadr + 4;endendendendendend
function[val] = getvalue(m,n,value,cow,row)% 这个函数通过 crs 存储的 value , cow ,row 计算出矩阵第m行 n列的元素的值并返回%%[lenth,~] = size(cow);if m>= lenthfprintf('Larger than the matrix\n')elseval = 0;for t=cow(m):(cow(m+1)-1)if n==row(t)val = value(t);returnendendendend
function [x, iter] = cg(b, x0,M, max_it, value, cow, row)x=x0;iter = 0;tolerance = 1.0e-6;N = length(b);%% 现在计算 A*x 的值temp= zeros(N,1);for t = 1:Nfor j = cow(t):(cow(t+1)-1)temp(t) = temp(t) + value(j)*x(row(j));endendr = b - temp;%% 开始循环for k=1:max_itif norm(r,2) <= tolerance*norm(b)iter = k-1;fprintf('\n Algorithm finds a solution!');returnendz = M*r;iter = iter + 1;if iter==1p = z;roo = r'*z;elseroos = roo;roo = r'*z;beta = roo*(1/roos);p = z + beta*p;endtemp= zeros(N,1);for t = 1:Nfor j = cow(t):(cow(t+1)-1)temp(t) = temp(t) + value(j)*p(row(j));endendw = temp;alpha = roo*(1/(p'*w));x = x + alpha*p;r = r - alpha * w;endend
可以看出数据的格式正确,最终方程的解为全部为 1 的列向量,长度为 用差分法求解如下二阶常微分方程边值问题
function [] = main()%用差分法求解二阶常微分方程N = input('Please Inupt N:')stap = 0;endp = 1;h = (endp-stap)/N;xarr = stap:h:endp;%% 获得差分方程的系数矩阵A = zeros(N+1);b = ones(N+1,1);for t = 1:N+2if t==1A(t,t) = 1;b(t) = 1;elseif t<=N+1A(t,t-1:t+1) = [1 -2 1];b(t) = -h*h*xarr(t)*xarr(t);elseA(t,t-1:t) = [1 (1+h)/(1-h) ];b(t) = h/(1-h);endendend%% 使用追赶法求解方程组% disp(A);% disp(b);y = zeros(N+2,1);u = zeros(N+2,1);l = zeros(N+2,1);x = zeros(N+2,1);u(1) = A(1,1);y(1) = b(1);for t = 2:N+2l(t) = A(t,t-1)/u(t-1);u(t) = A(t,t) - l(t)*A(t-1,t);y(t) = b(t) - l(t)*y(t-1);endx(N+2) = y(N+2)/u(N+2);for t = N+1:-1:1;x(t) = (y(t)-A(t,t+1)*x(t+1))/u(t);endxlswrite('res.xls',x,1);plot(xarr,x(1:N+1));% disp(x);end

用差分法求解如下 Laplace 方程
主函数 main
function [] = main()N = input('lxease Input N:');[value, cow, row, b]=getmatrix(N);% for m=1:(N+1)^2% fprintf('\n')% for n = 1:(N+1)^2% %fprintf('%f',m)% temp = getvalue(m,n,value,cow,row);% fprintf('%f\t',temp)% end% end% b;%% 使用基本迭代法求解方程组,( E+ T)x = b. then x = b-t*xres = solve_equation(value,cow,row,b);%% now plot the shape[y,x]=meshgrid(1:-1/N:0);Z =flipud( reshape(res,N+1,N+1));mesh(x,y,Z);end
getmatrix 函数 主要用来获得系数矩阵的压缩行存储格式
function [value, cow, row,b] = getmatrix(N)%% 使用addm 差值节点的地址信息。[xsta, xend, ysta, yend] = deal(0, 1, 0, 1);%多变量同时赋值xh = (xend-xsta)/N;yh = (yend-ysta)/N;addm = {};for m = 1:N+1for n = 1:N+1xtemp = xsta + (m-1)*xh;ytemp = ysta + (n-1)*yh;addm(m,n) = {[xtemp, ytemp, xtemp*ytemp ],};endend%disp(addm);%% 使用crs存储方法记录系数矩阵Avaluelen = (N*3-2)*N + N*(N-1)*2;value = ones(valuelen,1);cow = ones(N*N,1);row = ones(valuelen,1);tempadr = 1;%利用 tempadr 记录 value 数值变化的位置;cowadr = 1;%利用 cowadr 记录 cow 列号变化的位置;rowadr = 1 ;%利用 row 记录行变化的位置b = zeros(N*N+2*N+1,1);badr = 1;%% 从第一行开始逐个记录系数矩阵每行的for t = 1:N+1if t==1for n = 1:N+1value(tempadr) = 1;tempadr = tempadr + 1;cow(cowadr) = tempadr;cowadr = cowadr +1;row(rowadr) = (t-1)*(N-1)+n;rowadr = rowadr + 1;b(badr) = 0;badr = badr + 1;endelseif t<=Nvalue(tempadr) = 1;tempadr = tempadr + 1;cow(cowadr) = tempadr;cowadr = cowadr +1;row(rowadr) = (t-1)*(N+1)+1;rowadr = rowadr + 1;b(badr) = 0;badr = badr + 1;for n=2:Nvalue(tempadr:tempadr+4) = [-1/4 -1/4 1 -1/4 -1/4];tempadr = tempadr +5;cow(cowadr) = tempadr;cowadr = cowadr +1;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];rowadr = rowadr + 5;b(badr) = xh*xh*addm{t,n}(3);badr = badr + 1;endvalue(tempadr) = 1;tempadr = tempadr + 1;cow(cowadr) = tempadr;cowadr = cowadr +1;row(rowadr) = t*(N+1);rowadr = rowadr + 1;b(badr) = 0;badr = badr + 1;elsefor n = 1:N+1value(tempadr) = 1;tempadr = tempadr + 1;cow(cowadr) = tempadr;cowadr = cowadr +1;row(rowadr) = (t-1)*(N+1)+n;rowadr = rowadr + 1;b(badr) = 0;badr = badr + 1;endendendendend
solve_equation 主要使用基本迭代法求解方程组
function [ x ] = solve_equation( value, cow, row, b )%This function is used to solve equation%% get size of x;lenth = length(b);x0 = ones(lenth,1);x = x0;error = 1;%% 方程的解为xwhile error>=1e-5for m=1:lenthtemp = 0;if m == 1for t = 1:(cow(m)-1)if row(t) ~= mn = row(t);temp = temp + x0(n)*value(t);endendelsefor t = cow(m-1):(cow(m)-1)if row(t) ~= mn = row(t);temp = temp + x0(n)*value(t);endendendtemp = b(m)- temp;x(m) = temp;enderror = norm(x0-x,2);x0 = x;endend
getvalue 函数 检查系数矩阵是否正确
function[val] = getvalue(m,n,value,cow,row)% 这个函数通过 crs 存储的 value , cow ,row 计算出矩阵第m行 n列的元素的值并返回%%lenth = length(cow);if m>lenth || m<=0fprintf('Larger than the matrix')elseval = 0;if m==1for t=1:(cow(m)-1)if n == row(t)val =value(t);return;endendelseval = 0;for t=cow(m-1):(cow(m)-1)if n == row(t)val =value(t);return;endendendend
使用 freefem++ 通过变分法计算,代码如下:
real theta=4.*pi/3;real a=2. ,b=1.;func z=0;border a0(t=0,1){x=1; y=t;}border a1(t=0,1){x=1-t;y=1;}border a2(t=0,1){x=0; y=1-t;}border a3(t=0,1){x=t;y=0;}mesh Th = buildmesh(a0(50)+a1(50)+a2(50)+a3(50));fespace Vh(Th,P2);Vh phi,w,f=x*y;solve Laplace(phi,w)=int2d(Th)(dx(phi)*dx(w) + dy(phi)*dy(w))- int2d(Th)(f*w)+on(a0,phi=z)+on(a1,phi=z)+on(a2,phi=z)+on(a3,phi=z) ;plot(phi,wait=true);plot(Th,wait=true, ps="membraneTh.eps");savemesh(Th,"trace.msh");




在此输入正文