查找 FORTRAN 数组位置,4 维数组
嘿伙计们,我有一个问题。 如果给定一个 FORTRAN 中的四维数组,并被告知找到它的某个部分的位置(起始位置为 200,每个整数 4 个字节)。如果以行优先和列优先顺序存储,是否有公式可以查找位置。
基本上给定数组 A(x:X, y:Y, z:Z, q:q) 并告诉在 A(a,b,c,d) 处查找位置,查找位置的公式是什么
Hey guys, I have a question.
If given a four dimensional array in FORTRAN, and told to find a location of a certain part of it (with a starting location of 200 and 4 bytes per integer). Is there a formula to find the location if is stored in row-major and column-major order.
Basiically given array A(x:X, y:Y, z:Z, q:q) and told to find the location at A(a,b,c,d) what is the formula for finding the location
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
当将 C 库与 Fortran 一起使用时,这种情况总是会出现——例如,调用 MPI 例程尝试发送 Fortran 数组的特定子集。
Fortran 是
行优先,或更有用的是,第一个索引移动最快。也就是说,内存中按线性顺序排列在 A(1,2,3,4) 之后的项是 A(2,2,3,4)。因此,在上面的示例中,a 加 1 就是数组中索引跳转 1; b 中的跳跃 1 对应于 (X-x+1) 的跳跃; c 中的跳跃 1 对应于 (X-x+1)x(Y-y+1) 的跳跃,d 中的跳跃 1 对应于 (X-x+1)x(Y-y) 的跳跃+1)x(Z-z+1)。在基于 C 的语言中,情况恰恰相反; d 索引中的跳转 1 会在内存中移动 1 个索引; c 中的跳转将是 (Q-q+1) 的跳转,依此类推。如果您有 m 个索引,并且 ni 是第 i 中的(从零开始的)索引 从左侧开始索引,并且该索引的范围为 Ni,那么从起始位置开始的(从零开始的)索引如下所示:
如果上索引小于下索引,则乘积为 1。要查找从数组开头算起的字节数,您需要将其乘以对象的大小,例如 32 位整数为 4 个字节。
This comes up all the time when using C libraries with Fortran -- eg, calling MPI routines trying to send particular subsets of Fortran arrays.
Fortran is
row-major, ormore usefully, the first index moves fastest. That is, the item after A(1,2,3,4) in linear order in memory is A(2,2,3,4). So in your example above, an increase in a by one is a jump of 1 index in the array; a jump in b by one corresponds to a jump of (X-x+1); a jump in c by one corresponds to a jump of (X-x+1)x(Y-y+1), and a jump in d by one is a jump of (X-x+1)x(Y-y+1)x(Z-z+1). In C-based languages, it would be just the opposite; a jump of 1 in the d index would move you 1 index in memory; a jump in c would be a jump of (Q-q+1), etc.If you have m indicies, and ni is the (zero-based) index in the ith index from the left, and that index has a range of Ni, then the (zero-based) index from the starting position is something like this:
where the product is 1 if the upper index is less than the lower index. To find the number of bytes from the start of the array, you'd multiply that by the size of the object, eg 4 bytes for 32-bit integers.
自从我接触 FORTRAN 以来已经超过 25 年了。
我相信 FORTRAN 与许多其他语言不同,将数组布置在
列主要顺序。这意味着最左边的索引是
处理多重数据时更改最频繁的一个
线性顺序的维数组。一次
达到最左边索引的最大维度,将其设置回 1,假设基于 1
索引,并将下一级索引增加 1,然后重新开始该过程。
计算任何给定地址偏移量的索引配置
您需要知道 4 个数组维度中每个维度的值。没有这个
你做不到。
示例:
假设您的数组的尺寸为 2 x 3 x 4 x 5。这意味着
矩阵中总共有 2 * 3 * 4 * 5 = 120 个单元格。你想要对应的索引
到第 200 个字节。
这将是 (200 / 4) - 1 = 49 个单元(假设每个单元 4 个字节且偏移量为零
是第一个单元格)。
首先观察特定索引如何转换为偏移量...
元素 X(1,1,1,1) 出现在哪个单元格号?简单答案:1
元素 X(1, 2, 1, 1) 出现在第几个单元格中?自从我们骑车经过
最左边的维度必须是该维度加 1。换句话说,
2 + 1 = 3。 X(1, 1, 2, 1) 怎么样?我们循环穿过前两个维度
2 * 3 = 6 加 1 得到 7。最后 X(1, 1, 1, 2) 必须是:
2 * 3 * 4 = 24 加 1 得出第 25 个单元格。
请注意,下一个最右边的索引不会增加,直到单元格编号
超过其左侧索引的乘积。利用这个观察你可以
通过从最右边开始计算任何给定单元格编号的索引
最左边的索引如下:
最右边的索引每 (2 * 3 * 4 = 24) 个单元格递增。 24 变成 49(单元格编号
我们想要找到)的索引两次
剩下1个。添加 1(基于 1 的索引),为我们提供了最右边的
索引值为 2 + 1 = 3。下一个索引(向左移动)每 (2 * 3 = 12) 个单元格更改一次。 1 变成 12
零次,这给我们索引 0 + 1 = 1。下一个索引每 2 个单元格更改一次。 1 变成 2 0
次给出 incex 值为 1。对于最后一个(最左边的索引),只需将 1 添加到
剩下的,1 + 1 = 2。这为我们提供了以下参考 X(2, 1, 1, 2)。
通过将其返回到偏移量来进行双重检查:
((2 - 1) + ((1 - 1) * 2) + ((1 - 1) * 2 * 3) + ((3 - 1) * 2 * 3 * 4) = 49。
只需更改数字并对任意数量的维度使用相同的过程
和/或偏移量。
Been over 25 years since I did any FORTRAN.
I believe FORTRAN, unlike many other languages, lays arrays out in
column major order. That means the leftmost index is the
one that changes most frequently when processing a multi
dimensional array in linear order. Once
the maximum dimension of the leftmost index is reached, set it back to 1, assuming 1 based
indexing, and increment the next level index by 1 and start the process over again.
To calculate the index configuration for any given address offset
you need to know the value of each of the 4 array dimensions. Without this
you can't do it.
Example:
Suppose your array has dimensions 2 by 3 by 4 by 5. This implies a
total of 2 * 3 * 4 * 5 = 120 cells in the matrix. You want the index corresponding
to the 200th byte.
This would be the (200 / 4) - 1 = 49th cell (this assumes 4 bytes per cell and offset zero
is the first cell).
First observe how specific indices translate into offsets...
What cell number does the element X(1,1,1,1) occur at? Simple answer: 1
What cell number does element X(1, 2, 1, 1) occur at? Since we cycled through
the leftmost dimension it must be that dimension plus 1. In other words,
2 + 1 = 3. How about X(1, 1, 2, 1)? We cycled trough the first two dimensions
which is 2 * 3 = 6 plus 1 to give us 7. Finally X(1, 1, 1, 2) must be:
2 * 3 * 4 = 24 plus 1 gives the 25th cell.
Notice that the next righmost index does not increment until the cell number
exceeds the product of the indices to its left. Using this observation you can
calculate the indices for any given cell number by working from the rightmost
index to the left most as follows:
Right most index increments every (2 * 3 * 4 = 24) cells. 24 goes into 49 (the cell number
we want to find the indexing for) twice
leaving 1 left over. Add 1 (for 1 based indexing) that gives us a rightmost
index value of 2 + 1 = 3. Next index (moving left) changes every (2 * 3 = 12) cells. One goes into 12
zero times, this gives us index 0 + 1 = 1. Next index changes every 2 cells. One goes into 2 zero
times giving an incex value of 1. For the last (leftmost index) just add 1 to whatever is
left over, 1 + 1 = 2. This gives us the following reference X(2, 1, 1, 2).
Double check by working it back to an offset:
((2 - 1) + ((1 - 1) * 2) + ((1 - 1) * 2 * 3) + ((3 - 1) * 2 * 3 * 4) = 49.
Just change the numbers and use the same process for any number of dimensions
and/or offsets.
Fortran 的数组具有列优先顺序。这是在 http://en.wikipedia.org/wiki/Row-major_order 中描述的#列主要_顺序。在那篇文章的后面有一个高维数组的内存偏移量的方程。
Fortran has column-major order for arrays. This is described at http://en.wikipedia.org/wiki/Row-major_order#Column-major_order. Further down in that article there is the equation for the memory offset of a higher dimensional array.