1
我正在试图在Fortran90中编译一个代码(用ifort编译),其中我将两个矩阵相乘。我为编写了代码,因为其中一个矩阵很稀疏,所以你可以在不为整个矩阵分配内存的情况下进行乘法运算。引用传递正在改变矩阵的值
我有两个子例程。第一种方法是将稀疏矩阵(对角线上的k
和对角线两侧的l
)与矢量(b
)相乘。结果通过指针r
传递给主函数。我选择使用子程序并且没有功能,因为在这个子程序中我不需要再次分配内存。
subroutine matSparXVec(k, l, b, r)
implicit none
real, intent(in) ::k, l
real, intent(in), dimension(:) ::b
real, intent(out), dimension(:) ::r
integer ::ierr, i
r = (/&
k*b(1)+l*b(2), &
(l*b(i-1)+k*b(i)+l*b(i+1),i=2,size(b)-1),&
l*b(size(b)-1)+k*b(size(b))&
/)
end subroutine matSparXVec
第二子例程使用的第一个与另一矩阵相乘的稀疏矩阵(k
,l
)(B
):
subroutine matSparXMat(k, l, B, R)
implicit none
real, intent(in) ::k, l
real, intent(in), dimension(:,:) ::B
real, intent(out), dimension(:,:) ::R
call matsparXVec(k, l, B(1, :), R(1, :))
R(1, :) = R(1, :) + l * B(1, :)
do i = 2, (size(R)-2)
call matsparXVec(k,l,B(i,:),R(i,:))
R(i,:)=R(i-1,:)+R(i,:)
enddo
call matsparXVec(k,l,B(size(B),:),R(size(R),:))
R(size(R),:) = R(size(R),:) + l * B(size(B)-1,:)
end subroutine matSparXmat
现在出现的问题是,在一些地方的子程序matSparXmat
,我正在修改B(:,:)
指向的数据。在例如,代码:
implicit none
real, dimension(:,:), allocatable ::BB, RR
integer ::i, j, ierr, n, m
real, parameter ::k = 4.0, l = 1.0
n=3 !Dimension vector
m=3 !Dimension del segundo orden
allocate(RR(n,m), stat=ierr)
allocate(BB(n,m), stat=ierr)
forall(i = 1:size(BB(:,1)), j=1:size(BB(1,:)))
BB(i,j)=i+j
RR(i,j) = 0
endforall
do i=1,size(BB(:,1))
print *, BB(:,i)
enddo
call matSparXMat(k, l, BB, RR)
do i=1,size(BB(:,1))
print *, BB(:,i)
enddo
我得到的输出:
2.000000 3.000000 4.000000
3.000000 4.000000 5.000000
4.000000 5.000000 6.000000
4.6526092E+33 3.000000 1.9366391E+31
3.000000 4.000000 5.000000
4.000000 5.000000 6.000000
中,你可以看到,BB
值已被修改。
对!我也犯了同样的错误: 'call matsparXVec(k,l,B(size(B),:),R(size(R),:))!< - 这里 \t R (R),:) = R(size(R),:) + 1 * B(size(B)-1,:)!< - Here' 替换'size(B)'和'size )'size(B(:,1))'和size(R(:,1))'解决了整个问题。 –
啊哈,很高兴帮助! –
另外:我的意见是你应该将参数'm'和'n'传递给子程序,所以你不必担心'SIZE(B(:,1))'调用。 –