Pointers 引用传递正在更改矩阵的值

Pointers 引用传递正在更改矩阵的值,pointers,matrix,fortran90,subroutine,Pointers,Matrix,Fortran90,Subroutine,我正在尝试用Fortran90编写一个代码(使用ifort编译),其中我将两个矩阵相乘。我正在为此编写代码,因为其中一个矩阵是稀疏的,所以可以在不为整个矩阵分配内存的情况下进行乘法 我有两个子程序。第一个是将稀疏矩阵(k在对角线上,以及l在对角线两侧)和向量(b)相乘。结果通过指针r传递给主函数。我选择使用子例程而不使用函数,因为这样,我就不需要在子例程中再次分配内存 subroutine matSparXVec(k, l, b, r) implicit none re

我正在尝试用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
)相乘:

现在的问题是,在子例程
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
的值已被修改。

这里似乎出错了:

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

但是当我使用ifort 2013时,我得到了右上角的值
1.93…E+31
,但在其他方面它是正确的。不确定发生了什么,但如果我有什么想法,我会让你知道。

看起来这里出了问题:

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

但是当我使用ifort 2013时,我得到了右上角的值
1.93…E+31
,但在其他方面它是正确的。不知道发生了什么,但如果我有什么想法,我会让你知道。

好的!我也犯了同样的错误:
调用matsparXVec(k,l,B(大小B),:),R(大小R),:)!另外:我的意见是,您应该将参数
m
n
传递给子例程,这样您就不必担心
SIZE(B(:,1))
调用。或者,您可以使用
SIZE
调用在函数开头设置本地
m
n
;有时候我更喜欢这样,因为这样你就不需要更多的争论了。另外,通常最好使用
size(B,1)
来获取维度的大小,而不是
size(B(:,1))
。对!我也犯了同样的错误:
调用matsparXVec(k,l,B(大小B),:),R(大小R),:)!另外:我的意见是,您应该将参数
m
n
传递给子例程,这样您就不必担心
SIZE(B(:,1))
调用。或者,您可以使用
SIZE
调用在函数开头设置本地
m
n
;有时候我更喜欢这样,因为这样你就不需要更多的争论了。此外,通常最好使用
size(B,1)
来获取维度的大小,而不是
size(B(:,1))
*** glibc detected *** ./sparse_mults: free(): invalid next size (fast): 0x00000000014e4010 ***