 (
   (
 )
) 
 (
   (
 )
) 
 
| laplacian1d.m | 
| % laplacian1d.m % curl -O https://m-katsurada.sakura.ne.jp/program/fdm/laplacian1d.m % -(d/dx)^2 の差分近似 % [0,L] を N 等分した時の行列は h=L/N; a=laplacian1d(N-1)/(h*h); function a=laplacian1d(m) e=ones(m,1); a=spdiags([-e 2*e -e],-1:1,m,m); % 疎行列なので圧縮した形式 end | 
| 
>> a=laplacian1d(3));
>> full(a)
ans =
     2    -1     0
    -1     2    -1
     0    -1     2
 | 
 を
 を  等分する差分近似の場合は
 等分する差分近似の場合は
| 
>> L=1;
>> n=5;
>> h=L/n;
>> a=laplacian1d(n-1)/(h*h);
>> full(a)
ans =
   50.0000  -25.0000         0         0
  -25.0000   50.0000  -25.0000         0
         0  -25.0000   50.0000  -25.0000
         0         0  -25.0000   50.0000
 | 
 における
 における
 
 とするのは安直だけど)
 とするのは安直だけど)
| poisson1d_test1.m | 
| L=1 n=10 h=L/n x=linspace(0,L,n+1); a=laplacian1d(n-1)/(h*h); f=ones(n-1,1); u=a\f; u=[0; u; 0]; plot(x,u) figure(gcf) | 
 の場合は
 の場合は
| poisson1d_test2.m | 
| L=1 n=10 h=L/n x=linspace(0,L,n+1); a=laplacian1d(n-1)/(h*h); f=sin(x(2:n))'; u=a\f; u=[0; u; 0]; plot(x,u) figure(gcf) | 
 の場合は
 の場合は
| poisson1d_test3.m | 
| L=1 n=10 h=L/n x=linspace(0,L,n+1); a=laplacian1d(n-1)/(h*h); f=x.*(1-x); f=f(2:n)'; u=a\f; u=[0; u; 0]; plot(x,u) figure(gcf) | 
(2024/9 改訂版) 非同次Dirichlet境界値問題のプログラム。
| poisson1d_nh.m | 
| % poisson1d_nh.m
% 1次元領域におけるPoisson -△u=f (非同次Dirichlet境界条件) を差分法で解く
% 入手 curl -O https://m-katsurada.sakura.ne.jp/program/fdm/poisson1d_nh.m
% 解説 https://m-katsurada.sakura.ne.jp/labo/text/poisson1d.pdf
% (2024/9/4)。
function poisson1d_nh(N)
  arguments
    N=4 % デバッグ用
  end
  function K = poisson1d_mat(W,N)
    h=W/N;
    I=speye(N-1,N-1);
    v=ones(N-2,1);
    J=sparse(diag(v,1)+diag(v,-1));
    K=2*I-J;
    K=1/h^2*K;
  end
  % 想定している厳密解
  function val = exact_solution(x)% =x^4
    val = x .^ 4;
    %val = (x - 1.0/2).^2;
  end
  % f=-△u=-d^2u/dx^2
  function val = f(x)% = -u''(x) = -12x^2
    val = - 12 * x.^2;
    %val = 0 .* x - 2.0;
  end
  % 領域
  a=0; b=1;
  % 境界値
  alpha = exact_solution(a);
  beta = exact_solution(b);
  fprintf('a=%f, b=%f, u(a)=%f, u(b)=%f\n', a, b, alpha, beta);
  % 差分近似の行列
  h=(b-a)/N;
  fprintf('N=%d, h=%g\n', N, h);
  A=poisson1d_mat(b-a,N);
  if N <= 10
    disp('A='); disp(full(A));
  end
  % 連立方程式の右辺
  X=linspace(a,b,N+1);
  F=f(X(2:N)');
  F(1)=F(1)+alpha/h^2;
  F(N-1)=F(N-1)+beta/h^2;
  if N <= 10
    disp('X='); disp(X);
    disp('F=f(X)='); disp(F');
  end
  % 差分解を求める
  u=zeros(N+1,1);
  u(2:N)=A\F;
  % 境界値
  u(1)=alpha; u(N+1)=beta;
  % グラフを描く
  plot(X,u); title('差分解のグラフ'); drawnow; shg;
  figure
  plot(X,exact_solution(X')); title('厳密解のグラフ'); drawnow; shg;
  exact=exact_solution(X');
  error=norm(u-exact,inf);
  fprintf('max norm of error=%e\n', error);
end
 | 
入手するにはターミナルで
| curl -O https://m-katsurada.sakura.ne.jp/program/fdm/poisson1d_nh.m | 
これを実行するには、例えば
| cp -p poisson1d_nh.m ~/Documents/MATLAB | 
| >> poisson1d_nh(分割数はデフォールトの  が採用される。) | 
 を指定するため
 を指定するため
| >> poisson1d_nh(10) | 
上のサンプル・プログラムでは、
 と選び、
 と選び、
 ,
, 
 ,
,
 としてある。
 としてある。
 を
 を  から倍々にしていくと以下のようになった。
 から倍々にしていくと以下のようになった。
| N=10, h=0.1 max norm of error=2.500000e-03 N=20, h=0.05 max norm of error=6.250000e-04 N=40, h=0.025 max norm of error=1.562500e-04 N=80, h=0.0125 max norm of error=3.906250e-05 N=160, h=0.00625 max norm of error=9.765625e-06 N=320, h=0.003125 max norm of error=2.441406e-06 | 
 が
が 倍になると誤差は
倍になると誤差は 
 倍になる。
誤差は
 倍になる。
誤差は  になっているようで、ひとまずは納得できる。
 になっているようで、ひとまずは納得できる。