改变fortran中的数组维度 [英] changing array dimensions in fortran
问题描述
PROGRAM ARRAY
INTEGER,ALLOCATABLE :: A(:, :)
INTEGER :: N
ALLOCATE(A(N,N))
CALL ARRAY_EXPLICIT(A,N)
!或
CALL ARRAY_ASSUMED(A)
END PROGRAM ARRAY
SUBROUTINE ARRAY_EXPLICIT(A,N)
INTEGER :: N
INTEGER :: A(N ,N)
! bla bla
END SUBROUTINE ARRAY_EXPLICIT
SUBROUTINE ARRAY_ASSUMED(A)
INTEGER,ALLOCATABLE :: A(:, :)
N = SIZE(A,1)
! bla bla
END SUBROUTINE ARRAY_ASSUMED
您需要第二个显式接口,通常通过使用一个模块。
从FORTRAN77开始,我已经习惯了第一种选择,并且我认为如果您传递整个数组,这也是最有效的。 / p>
显式形状的好处在于我也可以调用一个子例程并将该数组视为一个向量而不是矩阵:
SUBROUTINE ARRAY_EXPLICIT(A,N)
INTEGER :: N
INTEGER :: A(N ** 2)
! bla bla
END SUBROUTINE ARRAY_EXPLICIT
我想知道是否有一种很好的方法可以做到这一点使用第二个假定的形状接口的东西,而不复制它。
请参阅RESHAPE内在函数,例如
http://gcc.gnu.org/ onlinedocs / gfortran / RESHAPE.html 另外,如果您想避免复制(在某些情况下,优化编译器可能无需重新设计复制,例如,如果RHS数组未被使用,但我不会指望它),从Fortran 2003开始,您可以使用边界重映射将指针指定给不同级别的目标。例如。类似于
程序ptrtest
real,pointer :: a(:)
real,pointer :: b(:, :)
integer :: n = 10
allocate(a(n ** 2))
a = 42
b(1 :n,1:n)=> a
结束程序ptrtest
There are basically two ways to pass arrays to a subroutine in Fortran 90/95:
PROGRAM ARRAY
INTEGER, ALLOCATABLE :: A(:,:)
INTEGER :: N
ALLOCATE(A(N,N))
CALL ARRAY_EXPLICIT(A,N)
! or
CALL ARRAY_ASSUMED(A)
END PROGRAM ARRAY
SUBROUTINE ARRAY_EXPLICIT(A,N)
INTEGER :: N
INTEGER :: A(N,N)
! bla bla
END SUBROUTINE ARRAY_EXPLICIT
SUBROUTINE ARRAY_ASSUMED(A)
INTEGER, ALLOCATABLE :: A(:,:)
N=SIZE(A,1)
! bla bla
END SUBROUTINE ARRAY_ASSUMED
where you need an explicit interface for the second, usually through the use of a module.
From FORTRAN77, I'm used to the first alternative, and I read this is also the most efficient if you pass the whole array.
The nice thing with the explicit shape is that I can also call a subroutine and treat the array as a vector instead of a matrix:
SUBROUTINE ARRAY_EXPLICIT(A,N)
INTEGER :: N
INTEGER :: A(N**2)
! bla bla
END SUBROUTINE ARRAY_EXPLICIT
I wondered if there is a nice way to do that kind of thing using the second, assumed shape interface, without copying it.
See the RESHAPE intrinsic, e.g.
http://gcc.gnu.org/onlinedocs/gfortran/RESHAPE.html
Alternatively, if you want to avoid the copy (in some cases an optimizing compiler might be able to do a reshape without copying, e.g. if the RHS array is not used afterwards, but I wouldn't count on it), as of Fortran 2003 you can assign pointers to targets of different rank, using bounds remapping. E.g. something like
program ptrtest
real, pointer :: a(:)
real, pointer :: b(:,:)
integer :: n = 10
allocate(a(n**2))
a = 42
b (1:n, 1:n) => a
end program ptrtest
这篇关于改变fortran中的数组维度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!