Integer :: NBE,ierr,RN,i,j
Real(kind=8), allocatable :: AA1(:,:),AA2(:,:)
NBE=40
RN=3*NBE-2
Allocate(AA1(3*NBE,3*NBE),AA2(3*NBE,RN),stat=ierr)
If (ierr .ne. 0) Then
print *, 'allocate steps failed 1'
pause
End If
Do i=1,3*NBE
Do j=1,3*NBE
AA1(i,j)=1
End Do
End Do
我想从矩阵AA1
中删除列97和113,然后此矩阵变为AA2
。我只想知道Fortran的任何命令是否可以实现此操作?
答案 0 :(得分:5)
这是一个简单的一个班轮:
AA2 = AA1(:,[(i,i=1,96),(i=98,112),(i=114,3*NBE)])
说明:
(内部部分)为索引[1,...,96,98,...,112,114,...,3*NBE]
构建临时数组
(外部)复制矩阵并仅考虑索引数组中的列
好的,我屈服于@IanBush ......更简单的是做三个专门的任务:
AA2(:,1:96) = AA1(:,1:96)
AA2(:,97:111) = AA1(:,98:112)
AA2(:,112:) = AA1(:,114:)
答案 1 :(得分:5)
Alexander Vogt's answer给出了使用向量下标来选择要包含的数组元素的概念。该答案使用
构造了矢量下标数组[(i,i=1,96),(i=98,112),(i=114,3*NBE)]
有些人可能会考虑
AA2 = AA1(:,[(i,i=1,96),(i=98,112),(i=114,3*NBE)])
在阅读中不太清楚。人们可以使用"临时"索引向量
integer selected_columns(RN)
selected_columns = [(i,i=1,96),(i=98,112),(i=114,3*NBE)]
AA2 = AA1(:,selected_columns)
但是这并没有解决数组构造函数不好的问题,特别是在更复杂的情况下。相反,我们可以创建一个掩码并使用我们常用的技术:
logical column_wanted(3*NBE)
integer, allocatable :: selected_columns(:)
! Create a mask of whether a column is wanted
column_wanted = .TRUE.
column_wanted([97,113]) = .FALSE.
! Create a list of indexes of wanted columns
selected_columns = PACK([(i,i=1,3*NBE)],column_wanted)
AA2 = AA1(:,selected_columns)
答案 2 :(得分:1)
我家里没有Fortran编译器,所以我不能测试它。但是,我做了一些事情:
i = 0
DO j = 1, 3*NBE
IF (j == 97 .OR. j == 113) CYCLE
i = i + 1
AA2(:, i) = AA1(:, j)
END DO
CYCLE
命令意味着不应该再执行循环的其余部分,并且应该开始下一次迭代。因此,i
不会增加,所以当j=96
,i=96
,j=98
然后i=97
,以及j=114
时i=112
1}}。
更多的话:由于Fortran的内存布局,您希望以最快的速度循环第一个索引,依此类推。因此,如果将代码更改为:
,则代码运行速度会更快Do j=1,3*NBE ! Outer loop over second index
Do i=1,3*NBE ! Inner loop over first index
AA1(i,j)=1
End Do
End Do
(当然,仅使用AA1(:,:) = 1
的{{1}}就可以轻松完成这种简单的初始化。