假设我有一个数组A(n,m)。是否可以在Fortran中对该数组进行子集化以创建新数组?例如,
A = 11 22 43 55
15 56 65 63
54 56 32 78
我想创建一个包含m-1列的数组B和满足A(:,2).eq的行。 56
所以B应该是:
B = 15 65 63
54 32 78
我甚至不知道如何开始,因为,例如,B的维度应该动态确定(我认为)
感谢您的帮助!
答案 0 :(得分:2)
你在找这样的东西吗?
function extractB(A) result(B)
integer, dimension(:,:), intent(in) :: A
integer, dimension(:,:), pointer :: B
integer :: nrowB, i, pos
nrowB = count( A(:,2)==56)
allocate( B(nrowB, size(A,2)-1 ) )
pos = 1
do i = 1, size(A,1)
if(A(i,2)==56)then
B(pos,1) = A(i,1)
B(pos,2:) = A(i,3:)
pos = pos+1
end if
end do
end function extractB
你称之为
B = extractB(A)
与B定义如下:
integer, dimension(:,:), allocatable :: B
我假设您的数组为整数。如果编译器将指针实现为返回值,则可以使用指向allocatable的指针。
====添加完整的程序====
module extract
contains
subroutine testExtract(A, B)
double precision, dimension(:,:), intent(in) :: A
double precision, dimension(:,:), intent(out), allocatable :: B
B = extractB(A)
end subroutine testExtract
function extractB(A) result(B)
double precision, dimension(:,:), intent(in) :: A
double precision, dimension(:,:), allocatable :: B
integer :: nrowB, i, pos
nrowB = count( A(:,2)==56)
allocate( B(nrowB, size(A,2)-1 ) )
pos = 1
do i = 1, size(A,1)
if(A(i,2)==56)then
B(pos,1) = A(i,1)
B(pos,2:) = A(i,3:)
pos = pos+1
end if
end do
end function extractB
end module extract
program test
use extract
integer, parameter :: n = 3
integer, parameter :: m = 4
double precision, dimension(3,4) :: A
double precision, dimension(:,:), allocatable :: B
A(1,:) = [11, 22, 43, 55]
A(2,:) = [15, 56, 65, 63]
A(3,:) = [54, 56, 32, 78]
print*, 'A :'
print*, int(A)
!B = extractB(A)
call testExtract(A, B)
print*, 'B'
print*, int(B)
end program
答案 1 :(得分:0)
循环显然是一个很好的方法,但如果你想要简洁,那么
integer, dimension(N,M) :: A
integer, allocatable :: B(:,:)
integer i
A = ...
B = A(PACK([(i,i=1,SIZE(A,1))],A(:,2)==56),[1,(i,i=3,SIZE(A,2))])
我应该解释一下,因为这里有很多愚蠢的事情。首先请注意[..]
是一个数组构造函数,而[(..)]
是一个带有隐含do的数组构造函数。
因此[(i,i=1,SIZE(A,1))]
会创建一个值为1, ..., N
且[1,(i,i=3,SIZE(A,2))]
的数组,其值为1, 3, ..., M
。这些形成了A的行和列的索引,错过了第二列。 PACK
部分为与掩码条件A(:,2)==56
匹配的行选择那些索引。
最后,我们使用向量下标来选择具有受限列的合适行。
这样做的唯一真正原因是受益于B
的自动分配。这非常有限。
如果没有良好的文档,请不要在实际代码中执行此操作。