我有一个N维数据集(比如实数),它存储为一维数组,附加一个维度数组,用于指定原始维度。
此外,还给出了从N-D指数中推导出1-D指数的函数,反之亦然。
我正在试图弄清楚如何为一般的N维索引(当然会将其转换为1D索引)从一些限制较低的索引到一组的do循环(或等效)上层指数。 所以我需要一个“N维”循环,其中不会覆盖所有值 - 只是数组的一部分,因此执行等效1D数组的线性索引是不相关的(至少没有修改)。
这是我的问题的示意图:
subroutine Test(Array,Dims,MinIndex,MaxIndex)
implicit none
real , dimension(1:), intent(inout) :: Array
integer, dimension(1:), intent(in) :: Dims,MinIndex,MaxIndex
integer, dimension(size(Dims)) :: CurrInd
integer :: 1Dindex
! size(Dims) can be 1, 2, 3 ,..., N
! size(MinIndex)==size(MaxIndex)==size(Dims)
! size(Array)==Product(Dims)
! 1Dindex=Get1dInd(NDindex,Dims)
! NDindex=GetNdInd(1Dindex,Dims)
! How do I actually preform this?
do CurrInd=MinIndex,MaxIndex
1Dindex=Get1dInd(CurrInd,Dims)
<Some operation>
enddo
end subroutine
我认为可以遍历Dims
数组并使用内部循环,但我无法正确编写该过程。
另一个对我不起作用的选项(可能因为我使用不正确?)是FORALL
,因为这需要单独指定每个索引。
答案 0 :(得分:2)
如果您在编译时知道数组的维度,则可以执行一系列嵌套的DO
循环,每个循环都在MinIndex
和MaxIndex
的成对组之间运行。由于您不了解尺寸,因此无法做到。
我能想到的最简单的策略是在所有1D索引上循环使用单个DO
循环。对于它们中的每一个,计算N维索引,并检查它是否在MinIndex
和MaxIndex
提供的范围内:如果是,继续做你需要的;如果不是,则丢弃该1D索引并转到下一个索引。如果指数是连续的,你可以做一些更聪明的事情,跳过你不会感兴趣的指数块。
do OneDindex = 1, size(Array)
CurrInd = GetNDInd(OneDindex, Dims)
if ((any(CurrInd<MinIndex)) .or. (any(CurrInd>MaxIndex))) cycle
! <Some operation>
end do
请注意,就索引操作而言,此策略与并行循环兼容。
另请注意,Fortran变量必须以字母开头:1Dindex
不是有效的Fortran变量名。
答案 1 :(得分:2)
这是我最终完成的实际过程。 我已经验证了它,并希望它对您像我一样有用。 (我知道这没有得到很好的评论,但是问题有所有细节,目前我的时间非常短)
此外,感谢rippero的帮助! 我决定不使用CYCLE方法,因为我假设只有执行实际的循环次数时,代码才能更有效地工作。
type Panel struct {
Width int
Height int
Message string
State [][]bool
}
func (state Panel.State) String() string {
line := state.parent.Message + "\n"
for x := 0; x < state.parent.Width; x++ {
for y := 0; y < state.parent.Height; y++ {
cell = state[x][y]
if cell {
line += "⚫️"
} else {
line += "⚪️"
}
}
line += "\n"
}
return line
}