将MATLAB代码转换用于使用Kronecker产品生成2D Laplacian矩阵的代码

发布于 2025-01-18 13:19:23 字数 2382 浏览 2 评论 0 原文

以下MATLAB代码使用Kronecker产品生成2D Laplacian矩阵 方法。

function A=A(N)

% Assemble the system matrix A
e = ones(N,1);
D = spdiags([e -2*e e], -1:1, N, N);
I = speye(N);
A = kron(D,I)+kron(I,D);
h = 1/(N+1);
A=A/h^2;

`

我需要将其转换为Python,以解决PDE边界值问题。

我的第一次尝试涉及使用 smop 。遇到了一大堆错误,并认为这是不值得的。

我的第二次尝试涉及通过使用 scipy 库。

这是我

import numpy as np
import scipy.sparse as sps


def build_laplacian_2D_kron(N):
    e = np.ones(shape=(N, 1))
    data = np.concatenate([e, -2*e, e] , axis= -1)
    diags = np.array([-1, 0, 1])                                                                                                                                                                                                                                                                                     
    D = sps.spdiags(data.transpose(), diags, N, N)
    I = sps.speye(N)
    A = np.kron(D, I) + np.kron(I, D)
    h = 1 / (N + 1)
    A = A / h ** 2
    A = sps.spmatrix.tocsc(A)

    return A


if __name__ == '__main__':
    build_laplacian_2D_kron(6)

试图运行代码时到目前为止

ValueError: offsets array must have rank 1

的 尝试。我一直在尝试修复它一段时间,但无济于事。

任何帮助都将不胜感激

更新:通过的输出

  (0, 0)    -36.0
  (1, 0)    9.0
  (2, 0)    9.0
  (3, 0)    0.0
  (0, 1)    9.0
  (1, 1)    -36.0
  (2, 1)    0.0
  (3, 1)    9.0
  (0, 2)    9.0
  (1, 2)    0.0
  (2, 2)    -36.0
  (3, 2)    9.0
  (0, 3)    0.0
  (1, 3)    9.0
  (2, 3)    9.0
  (3, 3)    -36.0

Process finished with exit code 0

ans =

   (1,1)      -36
   (2,1)        9
   (3,1)        9
   (1,2)        9
   (2,2)      -36
   (4,2)        9
   (1,3)        9
   (3,3)      -36
   (4,3)        9
   (2,4)        9
   (3,4)        9
   (4,4)      -36

n = 2 在我的输出中?任何帮助将不胜感激。

The following MATLAB code generates the 2D Laplacian matrix using a Kronecker product
approach.

function A=A(N)

% Assemble the system matrix A
e = ones(N,1);
D = spdiags([e -2*e e], -1:1, N, N);
I = speye(N);
A = kron(D,I)+kron(I,D);
h = 1/(N+1);
A=A/h^2;

`

I need to convert it to python in order to solve a PDE boundary value problem.

My first attempt involved using SMOP. Ran into a heap of errors and decided it wasn't worth the trouble.

My second attempt involved converting the code directly to python by using the numpy and scipy libraries.

Here's my attempt so far

import numpy as np
import scipy.sparse as sps


def build_laplacian_2D_kron(N):
    e = np.ones(shape=(N, 1))
    data = np.concatenate([e, -2*e, e] , axis= -1)
    diags = np.array([-1, 0, 1])                                                                                                                                                                                                                                                                                     
    D = sps.spdiags(data.transpose(), diags, N, N)
    I = sps.speye(N)
    A = np.kron(D, I) + np.kron(I, D)
    h = 1 / (N + 1)
    A = A / h ** 2
    A = sps.spmatrix.tocsc(A)

    return A


if __name__ == '__main__':
    build_laplacian_2D_kron(6)

When I attempt to run the code the following error shows up

ValueError: offsets array must have rank 1

The error is raised by the function scipy.sparse.spdiags when invoking sps.spdiags on line 9. I presume that the issue is mainly with the way I am initializing data and diags. I have been trying to fix it for quite some time now but to no avail.

Any help would be highly appreciated

Update: With the recommendations from hpaulj I fixed the errors in the python implementation and updated the code above. Here's the output for N = 2

  (0, 0)    -36.0
  (1, 0)    9.0
  (2, 0)    9.0
  (3, 0)    0.0
  (0, 1)    9.0
  (1, 1)    -36.0
  (2, 1)    0.0
  (3, 1)    9.0
  (0, 2)    9.0
  (1, 2)    0.0
  (2, 2)    -36.0
  (3, 2)    9.0
  (0, 3)    0.0
  (1, 3)    9.0
  (2, 3)    9.0
  (3, 3)    -36.0

Process finished with exit code 0

However it does not quite match with the output in matlab(which excludes the 0 entries in the resulting matrix)

ans =

   (1,1)      -36
   (2,1)        9
   (3,1)        9
   (1,2)        9
   (2,2)      -36
   (4,2)        9
   (1,3)        9
   (3,3)      -36
   (4,3)        9
   (2,4)        9
   (3,4)        9
   (4,4)      -36

What modification can I make to my python implementation to exclude the 0 entries in my output? Any help would be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文