2013-08-29 17 views
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 

第二子例程使用的第一个与另一矩阵相乘的稀疏矩阵(kl)(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值已被修改。

回答

1

看起来像它去错在这里:

do i = 2, (size(R)-2)      !<---- here 
    call matsparXVec(k,l,B(i,:),R(i,:)) 
    R(i,:)=R(i-1,:)+R(i,:) 
enddo 

size(R)=9size(R(:,1))=3。然而,使用gfortran我得到正确的输出与错误

*** glibc detected *** ./sparse_mults: free(): invalid next size (fast): 0x00000000014e4010 *** 

但是当我使用ifort 2013年,我得到你在右上角有值1.93...E+31,但除此之外,它是正确的。不知道发生了什么,但如果我拿出一些东西,我会让你知道。

+0

对!我也犯了同样的错误: '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))'解决了整个问题。 –

+0

啊哈,很高兴帮助! –

+0

另外:我的意见是你应该将参数'm'和'n'传递给子程序,所以你不必担心'SIZE(B(:,1))'调用。 –