改变fortran中的数组维度 [英] changing array dimensions in fortran

查看:153
本文介绍了改变fortran中的数组维度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基本上有两种方法可以将数组传递给Fortran 90/95中的子例程:

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆