我什么时候应该写一个矩阵向量函数来处理稀疏矩阵向量乘法?

计算科学 稀疏矩阵 迭代法 稀疏算子
2021-11-27 22:46:57

这学期,我一直在研究大型稀疏矩阵系统的迭代方法。但我有一些问题。对于大型稀疏矩阵,我们必须使用经济存储来存储它们。最流行的方式是压缩行存储或压缩列存储,即CRS、CCS格式,已被证明是最经济的方式。当我们使用迭代方法求解Ax=b时,我们必须重复计算矩阵向量乘法Ax因此,首先我们必须将稀疏矩阵存储在CRS 或 CCS中A格式,然后我们必须编写一个子程序来计算矩阵向量,这在我们的编码过程中非常麻烦。但是当我阅读从网站下载的关于迭代方法的matlab例程时,例如GMRES,MINRES,PCG,我发现作者只是使用matlab操作'*'来计算矩阵向量乘法,Ax,其中矩阵是matlab中的一种稀疏格式。例如,要计算Ay=Ax

n=4;
A = gallery('poisson',n);
x=rand(n^2,1);
y=A*x

至于matlab中的类似代码,我发现没有人编写单个子程序来计算矩阵向量我不明白,因为在许多关于大型稀疏矩阵迭代方法的专着中,他们总是讨论稀疏矩阵存储和计算矩阵向量的经济方式。但是我发现没有人在使用 matlab 时这样做。为什么这个?因为使用matlab?还是其他原因?Ax

如果我们不使用matlab,比如使用C、Python、Fortran语言,我们还能像matlab一样使用简单的y=A*x吗?欢迎任何建议。

2个回答

使用稀疏矩阵格式(如 CSR)将矩阵和向量相乘并不难,如果您为稀疏线性系统编写线性求解器库,这是一个基本且常见的操作。以Yousef Saad 的SPARSEKIT为例。在代码中,您会发现第一个子程序之一就是他所说的“amux”。您可以在下面查看它。可以看出,它相当简单。希望您能够在例如 MATLAB 中做同样的事情。

因此,当您处理稀疏矩阵时,您应该为此操作执行一个特殊的稀疏矩阵 - 向量积函数,并且可能他们在 MATLAB 中有它。他们是否能够重载“*”运算符 - 可能是,但我不确定是不是这样。

subroutine amux ( n, x, y, a, ja, ia )

!*****************************************************************************80
!
!! AMUX multiplies a CSR matrix A times a vector.
!
!  Discussion:
!
!    This routine multiplies a matrix by a vector using the dot product form.
!    Matrix A is stored in compressed sparse row storage.
!
!  Modified:
!
!    07 January 2004
!
!  Author:
!
!    Youcef Saad
!
!  Parameters:
!
!    Input, integer ( kind = 4 ) N, the row dimension of the matrix.
!
!    Input, real X(*), and array of length equal to the column dimension 
!    of A.
!
!    Input, real A(*), integer ( kind = 4 ) JA(*), IA(NROW+1), the matrix in CSR
!    Compressed Sparse Row format.
!
!    Output, real Y(N), the product A * X.
!
  implicit none

  integer ( kind = 4 ) n

  real ( kind = 8 ) a(*)
  integer ( kind = 4 ) i
  integer ( kind = 4 ) ia(*)
  integer ( kind = 4 ) ja(*)
  integer ( kind = 4 ) k
  real ( kind = 8 ) t
  real ( kind = 8 ) x(*)
  real ( kind = 8 ) y(n)

  do i = 1, n
!
!  Compute the inner product of row I with vector X.
!
    t = 0.0D+00
    do k = ia(i), ia(i+1)-1
      t = t + a(k) * x(ja(k))
    end do

    y(i) = t

  end do

  return
end

感谢您的所有回复,我在matlab中做了一些实验,并确认matlab确实自动优化地使用了稀疏矩阵向量乘法。例如,

clc;clear;
rng(0);
n=160;
A = gallery('poisson',n);%  A is n^2 * n^2 and sparse matrix
x=rand(n^2,1);

tic;A*x;toc;

tic;full(A)*x;toc;

结果是

Elapsed time is 0.001107 seconds.
Elapsed time is 7.549824 seconds.

我的 CPU 是 8GB 和 matlab 2018b。从上面的结果可以看出,在 matab 中编码时,矩阵-向量乘法会自动选择最佳的执行方式。因此,我们不需要编写子程序来单独计算Ax ,非常方便。