在运行时设置数组的等级 [英] Set array's rank at runtime

查看:19
本文介绍了在运行时设置数组的等级的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了一个程序来读取包含多维数据(最常见的是 3D,但也可能出现 2D)的文件.为了提高简单性,我想将数据存储在相同等级的数组中(或假装为一个的数组),即使用三维数组存储 3D 数据等;问题是程序只知道读取数据文件的维度.

I have written a program which reads a file containing multidimensional data (most commonly 3D, but 2D could occur as well). To heighten simplicity I would like to store the data in an array of the same rank (or something pretending to be one), i.e. using a three-dimensional array for 3D data, etc.; the trouble is that the program only learns about the dimensionality on reading the data file.

目前我将所有数据存储在一个等级为 1 的数组中,并根据元素的坐标计算该数组中每个元素的索引(这也被建议 此处).但是,我也读过关于指针等级重映射的文章,这看起来非常优雅,正是我一直在寻找的内容,因为它可以让我废弃我的数组索引确定过程(这可能远低于场景).但是,现在看来我面临着与直接声明多维数组相同的问题——如何进行声明?同样,它需要有关排名的信息.

Currently I store all data in an array of rank one and calculate each element's index in that array from the element's coordinates (this was also suggested here). However, I have also read about pointer rank remapping, which seems very elegant and just what I have been looking for, as it would allow me to scrap my procedures for array index determination (which are probably far less efficient than what goes on behind the scenes). Now, however, it looks like I'm facing the same problem as with directly declaring a multidimensional array - how to do the declaration? Again, it requires information about the rank.

我如何使用指针等级重新映射或其他一些更合适的技术来在运行时设置数组的等级 - 以防万一这完全可以完成.还是我最好坚持我目前使用的秩一数组?

How could I use pointer rank remapping or some other, more suitable technique for setting an array's rank at runtime - in case this can be done at all. Or am I best off sticking to the rank one-array that I am currently using?

推荐答案

我曾经问过类似的问题,即如何将二维数组视为一维,请参见此处:在 fortran 中更改数组维度.

I once asked something similar, i.e. how to treat a two-dimensional array as one dimension, see here: changing array dimensions in fortran.

答案是关于指针的 RESHAPE 内在的,但是似乎没有办法使用相同的数组 name 除非你使用子程序包装器,但是你需要回调来让最终的子程序与只有一个名字,所以问题会更大.

The answers were about the RESHAPE instrinsic of pointers, however there seems to be no way to use the same array name unless you use subroutine wrappers, but then you need callbacks to have the eventual subroutine with only one name, so the problems get larger.

program test
    real, allocatable :: data(:)
    allocate(data(n_data))
    ! read stuff, set is_2d and sizes
    if (is_2d) then
        call my_sub2(data, nX, nY)
    else
        call my_sub3(data, nX, nY, nZ)
    end if
end program test

subroutine my_sub2(data, nX, nY)
    real :: data(nx,nY)
    ! ...
end subroutine my_sub2

subroutine my_sub3(data, nX, nY, nZ)
    real :: data(nx,nY,nZ)
    ! ...
end subroutine my_sub3

作为替代,将第三等级设置为 1:

as an alternative, set the third rank to 1:

program test
    real, allocatable, target:: data(:)
    real, pointer:: my_array(:,:,:)
    logical is_2d
    n_data = 100
    allocate(data(n_data))
    ! read stuff, determine is_2d and n
    if (is_2d) then
        i=n
        j=n
        k=1
    else
        i=n
        j=n
        k=n
    end if
    my_array(1:i,1:j,1:k) => data
    write(*,*) my_array
end program test

然后您将 2D 案例作为具有第三维 1 的特殊 3D 案例进行处理.

Then you handle the 2D case as a special 3D case with third dimension 1.

另外,在将非连续数组传递给具有显式形状数组的子例程时要小心:http://software.intel.com/sites/products/documentation/hpc/compilerpro/en-us/fortran/lin/compiler_f/optaps/fortran/optaps_prg_arrs_f.htm

also, beware when passing non-contiguous arrays to subroutines with explicit-shape arrays: http://software.intel.com/sites/products/documentation/hpc/compilerpro/en-us/fortran/lin/compiler_f/optaps/fortran/optaps_prg_arrs_f.htm

这篇关于在运行时设置数组的等级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆