有没有办法可以访问数组n
的{{1}}元素,其中n是1D数组,a
是size(n)
的等级。< / p>
编辑2015-08-22 15:21
我在考虑与
类似的东西a
所以我可以像这样打电话
program Example1D
integer :: a(6), b(1)
a = reshape( (/ (i , i = 1, size(a) ) /) , shape(a) )
b = (/ 5 /)
write(*,*) a(b)
end program Example1D
答案 0 :(得分:0)
您正在尝试使用 vector-subscript (例如Fortran 2008,cl.6.5.3.3.2)。这允许您使用向量(1D数组)从数组维度中选择随机元素。但是,这并不能完全用于从多个维度中选择元素。
从6.5.3.3(强调我的):
在具有 section-subscript-list 的 array-section 中,每个 subscript-triplet 和 vector-subscript 在子节中 脚本列表表示一系列下标,可能为空。 这样的序列中的每个下标应为 除非序列为空,否则在其维度的范围内。数组部分是来自的元素集 由所有可能的下标列表确定的数组,可从单个下标或下标序列获得 由每个部分下标指定。
如果您的示例代码中的目标是使用向量a(5,3)
选择元素b = [5, 3]
,那么您可以从
write (*,*) a(b) ! doesn't work
为:
write (*,*) a(b(1),b(2)) ! does work
只要为b
的每个维使用1D部分,就可以执行更高级别a
更复杂的数组部分。例如,如果a
是一个5x5数组,则可以使用a
作为2x2数组的角点:
integer :: b(2,2) ! 2 dimensional
b(1,:) = [1,5]
b(2,:) = [1,5]
write (*,*) a(b(1,:),b(2,:)) ! prints a(1,1), a(5,1), a(1,5), a(5,5)
在下面的评论中,您要求将其抽象为n维数组a
。下面是一个我认为丑陋的函数,因为它需要以我认为是hack的方式使用c interop。您还需要一个更新的编译器来使用代码,因为它依赖于假定等级数组。这是一个包含子程序的模块,该子程序采用包含要打印的二维b
数组索引,并使用n维a
来获取值。
module future
implicit none
contains
subroutine print_array_vector(a, b)
use, intrinsic :: iso_c_binding, only: c_loc, c_f_pointer
implicit none
integer, dimension(..), target :: a
integer, dimension(:,:) :: b
integer :: a_rank, b_len1
integer, dimension(:,:,:), pointer :: a3
integer, dimension(:,:), pointer :: a2
integer, dimension(:), pointer :: a1
a_rank = rank(a)
if (a_rank /= size(b,1)) then
print *, "Rank mismatch between array and vector"
return
end if
if (a_rank == 3) then
call c_f_pointer(c_loc(a), a3, shape=[size(a,1), size(a,2), size(a,3)])
print *, a3(b(1,:),b(2,:),b(3,:))
else if (a_rank == 2) then
call c_f_pointer(c_loc(a), a2, shape=[size(a,1), size(a,2)])
print *, a2(b(1,:),b(2,:))
else if (a_rank == 1) then
call c_f_pointer(c_loc(a), a1, shape=[size(a,1)])
print *, a1(b(1,:))
else
print *, "Unsupported rank"
return
end if
end subroutine print_array_vector
end module future
这接受假定等级 a
,除了作为实际参数传递给C接口之外,它不能直接在Fortran中使用。但是,我们可以使用c-interop的其他部分来获取a
的C指针,然后将其转换为适当形状的Fortran指针。现在我们以可用的形式a
,但我们必须在if
/ else
块内正确引用不同的情况。我只实现了最多3维a
,其余部分留给了读者。
要使用此功能,以下是一个示例:
program test
use future
implicit none
integer :: a3(5,5,5), a2(5,5), a1(5)
integer :: b3(3,2), b2(2,2), b1(1,2)
integer :: i
a3 = reshape([(i,i=1,125)],shape(a3))
a2 = reshape([(i,i=1,25)],shape(a2))
a1 = [(i,i=1,5)]
b3 = reshape([1,1,1,5,5,5],shape(b3))
b2 = reshape([1,1,5,5],shape(b2))
b1 = reshape([1,5],shape(b1))
call print_array_vector(a1,b1)
call print_array_vector(a2,b2)
call print_array_vector(a3,b3)
end program test
这构造了一个3-dim a
,一个2-dim a
和一个1-dim a
,以及一些2-dim b
&#39 ; s带有数组角点的位置,然后我们调用函数从数组中打印向量的位置。
% ./arraysection
1 5
1 5 21 25
1 5 21 25 101 105 121 125
我用gfortran 5.2编译并测试了这个,我不知道在其他版本的gfortran或其他Fortran编译器中支持假定等级数组的当前状态。