Matlab 生成有限差分的矩阵

Matlab 生成有限差分的矩阵,matlab,numerical-methods,pde,numerical-analysis,Matlab,Numerical Methods,Pde,Numerical Analysis,我正在为一个2D PDE问题实施一个有限差分方案。我希望避免使用循环来生成有限差分。例如,为了生成u(x,y)xx的二阶中心差,我可以将u(x,y)乘以以下值: 对于u_xy=(u_{i+1,j+1}+u_{i-1,j-1}-u_{i-1,j+1}-u_{i+1,j-1})/(4dxdy)有一个好的矩阵表示吗?这是一个很难编码的问题,因为它是在2D中-我想用一些矩阵乘以u(x,y)以避免循环。非常感谢 显然,您可以自己创建矩阵,但在Matlab中有用于此目的的tridiag 比如说 >&

我正在为一个2D PDE问题实施一个有限差分方案。我希望避免使用循环来生成有限差分。例如,为了生成u(x,y)xx的二阶中心差,我可以将u(x,y)乘以以下值:


对于u_xy=(u_{i+1,j+1}+u_{i-1,j-1}-u_{i-1,j+1}-u_{i+1,j-1})/(4dxdy)有一个好的矩阵表示吗?这是一个很难编码的问题,因为它是在2D中-我想用一些矩阵乘以u(x,y)以避免循环。非常感谢

显然,您可以自己创建矩阵,但在Matlab中有用于此目的的
tridiag

比如说

>> full(gallery('tridiag',5,-1,2,-1))
ans=


如果你的点存储在一个
N×N
矩阵中,那么,如你所说,左乘你的有限差分矩阵可以得到关于
u_{xx}
的二阶导数的近似值。右乘有限差分矩阵的转置相当于近似值
u_{yy}
。通过左乘和右乘(例如,中心差分矩阵),可以获得混合导数
u_{xy}
的近似值

delta_2x =

     0     1     0     0     0
    -1     0     1     0     0
     0    -1     0     1     0
     0     0    -1     0     1
     0     0     0    -1     0
(然后除以因子
4*Dx*Dy
),如下

U_xy = 1/(4*Dx*Dy) * delta_2x * U_matrix * delta_2x';
如果将矩阵转换为
N^2
向量

U_vec = U_matrix(:);
然后,这些运算符可以用a表示,在MATLAB中实现为:我们有

对于有限差分矩阵

U_xy_vec = 1/(4*Dx*Dy)*(kron(delta_2x,delta_2x)*U_vec);
相反,如果你有一个
N-by-M
矩阵
U\U mat
,那么左矩阵乘法等于
kron(eye(M),delta\U 2x\U N)
,右矩阵乘法等于
kron(delta\U 2y\U M,eye(N))
,其中
delta\U 2y\U M
delta\U 2x\U N
)是
M-by-N
)中心差分矩阵,因此操作是

U_xy_vec = 1/(4*Dx*Dy) * kron(delta_2y_M,delta_2y_N)*U_vec;
下面是一个MATLAB代码示例:

N = 20;
M = 30;
Dx = 1/N;
Dy = 1/M;

[Y,X] = meshgrid((1:(M))./(M+1),(1:(N))/(N+1));

% Example solution and mixed derivative (chosen for 0 BCs)
U_mat = sin(2*pi*X).*(sin(2*pi*Y.^2));
U_xy = 8*pi^2*Y.*cos(2*pi*X).*cos(2*pi*Y.^2);

% Centred finite difference matrices
delta_x_N = 1/(2*Dx)*(diag(ones(N-1,1),1) - diag(ones(N-1,1),-1));
delta_y_M = 1/(2*Dy)*(diag(ones(M-1,1),1) - diag(ones(M-1,1),-1));

% Cast U as a vector
U_vec = U_mat(:);

% Mixed derivative operator
A = kron(delta_y_M,delta_x_N);

U_xy_num = A*U_vec;
U_xy_matrix = reshape(U_xy_num,N,M);

subplot(1,2,1)
contourf(X,Y,U_xy_matrix)
colorbar
title 'Numeric U_{xy}'
subplot(1,2,2)
contourf(X,Y,U_xy)
colorbar
title 'Analytic U_{xy}'

使用MATLAB中可用的稀疏功能生成有限差分近似矩阵是一个不错的选择。。它节省了大量(实际上非常多)内存…

您的编程语言/环境是什么?@karakfa刚刚在Matlab抱歉,我应该更具体地回答我的问题。我知道如何在matlab中创建三对角矩阵,这是我想知道的偏导数矩阵的结构。也许我应该问一下comp sci?对不起,我没注意,我以为你在描述这个矩阵的结构。我会考虑的。你的意思是
u_ij=…
而不是方程中的
u xy
。我认为简单的矩阵乘法是不可能的,因为你所依赖的矩阵索引既不匹配行索引,也不匹配列索引。谢谢:)u xy表示部分w.r.t.x&y。因此,在u_{i,j}点,推导可以用上面我写的方案来近似。我想知道,例如,你是否把一个3x3矩阵变成了一个1 x 9行向量,然后乘以一个9 x 9矩阵(基本上摆脱了2D问题)。这似乎是一个相当笨拙的方法,但我认为一定有更好的东西在那里。谢谢,这是一个很好的答案。如果u(x1,x2)在一个矩形域上呢?事情变得有点棘手,但这是可能的。你想在每个方向上得到不同数量的点是吗?是的,我想概括一下:)我基本上已经完成了你建议的第一部分。例如,如果将其离散化为6x4网格,我将生成两条三对角线,4x4(表示u_xx)和6x6(表示u_yy),其结构与我在原始帖子中使用的结构相同。do u*(4x4)代表u_xx,而(6x6)*u代表u_yy。谢谢,我要试一试@Mike Well矩阵较大且相对稀疏(有点带状,可能宽度
max(N+1,M+1)
,不对称),因此您可能希望避免直接计算它或它的逆矩阵。不确定该建议什么,当然也想不到快速解决方案。
U_xy_vec = 1/(4*Dx*Dy) * kron(delta_2y_M,delta_2y_N)*U_vec;
N = 20;
M = 30;
Dx = 1/N;
Dy = 1/M;

[Y,X] = meshgrid((1:(M))./(M+1),(1:(N))/(N+1));

% Example solution and mixed derivative (chosen for 0 BCs)
U_mat = sin(2*pi*X).*(sin(2*pi*Y.^2));
U_xy = 8*pi^2*Y.*cos(2*pi*X).*cos(2*pi*Y.^2);

% Centred finite difference matrices
delta_x_N = 1/(2*Dx)*(diag(ones(N-1,1),1) - diag(ones(N-1,1),-1));
delta_y_M = 1/(2*Dy)*(diag(ones(M-1,1),1) - diag(ones(M-1,1),-1));

% Cast U as a vector
U_vec = U_mat(:);

% Mixed derivative operator
A = kron(delta_y_M,delta_x_N);

U_xy_num = A*U_vec;
U_xy_matrix = reshape(U_xy_num,N,M);

subplot(1,2,1)
contourf(X,Y,U_xy_matrix)
colorbar
title 'Numeric U_{xy}'
subplot(1,2,2)
contourf(X,Y,U_xy)
colorbar
title 'Analytic U_{xy}'