Matrix Fortran语言中的稀疏矩阵向量积
知道我的矩阵是稀疏的,我如何用Fortran进行矩阵向量乘法 例如,我想计算3x3矩阵之间的乘积Matrix Fortran语言中的稀疏矩阵向量积,matrix,vector,fortran,sparse-matrix,Matrix,Vector,Fortran,Sparse Matrix,知道我的矩阵是稀疏的,我如何用Fortran进行矩阵向量乘法 例如,我想计算3x3矩阵之间的乘积 0 1 2 3 0 0 4 0 5 矢量呢 1 2 3 我曾考虑在不等于零的情况下存储行、列以及值,但没有任何结果。除非您想了解如何实现这一点,否则可以使用稀疏矩阵库。例如SPARSKIT或suitesparse。除非您想了解如何实现此功能,否则可以使用稀疏矩阵库。例如SPARSKIT或suitesparse。首先,您需要确定稀疏代数还是密集代数的速度更快: 实际计算中涉及的矩阵大小是多少?如
0 1 2
3 0 0
4 0 5
矢量呢
1
2
3
我曾考虑在不等于零的情况下存储行、列以及值,但没有任何结果。除非您想了解如何实现这一点,否则可以使用稀疏矩阵库。例如SPARSKIT或suitesparse。除非您想了解如何实现此功能,否则可以使用稀疏矩阵库。例如SPARSKIT或suitesparse。首先,您需要确定稀疏代数还是密集代数的速度更快:
实际计算中涉及的矩阵大小是多少?如果它是某个维度m,n,其中,比如说,m首先,你需要决定稀疏代数还是稠密代数会更快:
实际计算中涉及的矩阵大小是多少?如果它是某个维度m,n,比如说,mI想学习如何在有限差分2d上实现它。谢谢,我要试试这些。我想学习如何在二维有限差分上实现它。谢谢,我要试试这些。我只是想说Fortran 77已经过时30年了——如果你想这样做,为什么要在有更好的工具可用的时候使用它呢?因为这是我第一年在课堂上学习Fortran,他们希望我们从底层学习。稍后我们将使用Fortran 95。我只想说Fortran 77已经过时30年了。如果你想这样做,为什么要在有更好的工具可用的时候使用它呢?因为这是我第一年在课堂上使用Fortran,他们希望我们从底层学习它。我们将使用Fortran 95 laterNice,这是一次很好的尝试,可以将这个问题拖到这个千年!只需一条评论,使用ieee_算术内在模块中的ieee_值比从这里的神奇常数转换生成NaN更清晰。很好,很好的尝试将问题拖到这个千年!只需一个注释,使用ieee_算术内在模块中的ieee_值,比从这里的神奇常数转换生成NAN更清晰。
module sparse_CSR
use iso_fortran_env
implicit none
public
type, public :: CSRMatrix
integer :: m = 0
integer :: n = 0
integer, allocatable :: rowPtr(:)
integer, allocatable :: colPtr(:)
real(real64), allocatable :: aij(:)
end type CSRMatrix
contains
! Convert a dense matrix to a sparse one.
pure type(CSRMatrix) function dense_to_sparse(matrix) result(sparse)
real(real64), intent(in) :: matrix(:,:)
integer :: ierr,m,n,nnz,row,nnz_row,j1,j2,colIndex(size(matrix,2))
logical :: row_nonZeroes(size(matrix,2))
! Get matrix size
m = size(matrix,1)
n = size(matrix,2)
nnz = count(matrix/=0.0_real64)
! Create an array of indices
forall(j1=1:n) colIndex(j1) = j1
! Set matrix size
sparse%m = m
sparse%n = n
! Allocate data
allocate(sparse%rowPtr(m+1),sparse%colPtr(nnz),sparse%aij(nnz))
! Fill rows
sparse%rowPtr(1) = 1
fill_by_rows: do row=1,m
row_nonZeroes = matrix(row,:)/=0.d0
nnz_row = count(row_nonZeroes)
j1 = sparse%rowPtr(row)
j2 = j1+nnz_row-1
sparse%colPtr(j1:j2) = pack(colIndex ,row_nonZeroes)
sparse%aij (j1:j2) = pack(matrix(row,:),row_nonZeroes)
! Set pointer for beginning of next line
sparse%rowPtr(row+1) = j2+1
end do fill_by_rows
end function dense_to_sparse
! Compute matrix-vector product
pure function sparse_matvec(matrix,vector) result(MxV)
type(CSRMatrix), intent(in) :: matrix
real(real64), intent(in) :: vector(:)
real(real64) :: MxV(matrix%m)
integer :: row,j,j1,j2,col
real(real64) :: aij
! Check size. Cannot stop in a pure procedure.
! So, return NaNs
if (size(vector,1)/=matrix%n) then
MxV(:) = transfer(-2251799813685248_int64, 1._real64)
return
endif
! Compute product by rows
do row=1,matrix%m
j1 = matrix%rowPtr(row)
j2 = matrix%rowPtr(row+1)-1;
MxV(row) = 0.0_real64
do j=j1,j2
col = matrix%colPtr(j)
aij = matrix%aij(j)
MxV(row) = MxV(row) + aij*vector(col)
end do
end do
end function sparse_matvec
end module sparse_CSR
program test_sparse
use sparse_CSR
use iso_fortran_env
implicit none
real(real64) :: dense(3,3) = reshape(real([0,3,4,1,0,0,2,0,5],real64),[3,3])
real(real64) :: vector(3) = real([1,2,3],real64)
type(CSRMatrix) :: sparse
real(real64) :: MxV(3)
sparse = dense_to_sparse(dense)
MxV = sparse_matvec(sparse,vector)
print *, 'MxV = ',MxV
end program test_sparse
MxV = 8.0000000000000000 3.0000000000000000 19.000000000000000