可变大小数组的Fortran数组 [英] Fortran array of variable size arrays

查看:667
本文介绍了可变大小数组的Fortran数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题的简化说明:

在商店中恰好有 maxSize 人购物.他们每个人都有一个购物清单,其中包含商品价格(整数).使用Fortran数组,如何表示所有购物清单.购物清单可能包含任意个项目(1、10、1000000000).

There are exactly maxSize people shopping in a store. Each of them has a shopping list, containing the price of items (as integers). Using Fortran arrays, how can I represent all the shopping lists. The shopping lists may contain any number of items (1, 10, 1000000000).

(注意:实际问题要复杂得多.甚至与购物无关.)

(NOTE: The actual problem is far more complicated. It is not even about shopping.)

懒惰的方法是:

integer :: array(maxSize, A_REALLY_BIG_NUMBER)

但是,这非常浪费,我基本上希望第二维是可变的,然后将其分别分配给每个人.

However, this is very wasteful, I basically want the second dimension to be variable, and then allocate it for each person seperately.

显而易见的尝试,注定要失败:

The obvious attempt, doomed to failure:

integer, allocatable :: array(:,:)
allocate(array(maxSize, :)) ! Compiler error

Fortran似乎要求数组在每个维度上的大小都是固定的.

Fortran seems to require that arrays have a fixed size in each dimension.

这很奇怪,因为大多数语言将多维数组视为数组数组",因此您可以在数组数组"中分别设置每个数组的大小.

This is wierd, since most languages treat a multidimensional array as an "array of arrays", so you can set the size of each array in the "array of arrays" seperately.

这是起作用的事情:

type array1D
    integer, allocatable :: elements(:) ! The compiler is fine with this!
endtype array1D

type(array1D) :: array2D(10)
integer :: i

do i=1, size(array2D)
    allocate(array2D(i)%elements(sizeAt(i))
enddo

如果这是唯一的解决方案,我想我会用它.但是我很希望会有一种使用内在函数来做到这一点的方法.必须为这种简单的事情定义自定义类型有点烦人.

If this is the only solution, I guess I will use it. But I was kind of hoping there would be a way to do this using intrinsic functions. Having to define a custom type for such a simple thing is a bit annoying.

在C语言中,由于数组基本上是具有奇特语法的指针,因此可以使用指针数组来做到这一点:

In C, since an array is basically a pointer with fancy syntax, you can do this with an array of pointers:

int sizeAt(int x); //Function that gets the size in the 2nd dimension
int * array[maxSize];

for (int x = 0; x < maxSize; ++x)
        array[x] = (int*)(calloc(sizeAt(x) , sizeof(int)));

Fortran似乎也有指针.但是我发现的唯一的教程都说从不使用这些东西"或类似的东西.

Fortran seems to have pointers too. But the only tutorials I have found all say "NEVER USE THESE EVER" or something similar.

推荐答案

您似乎在抱怨Fortran不是C.是的.标准委员会选择以不同的方式做事的原因可能有无数个,但这里有一些想法:

You seem to be complaining that Fortran isn't C. That's true. There are probably a near infinite number of reasons why the standards committees chose to do things differently, but here are some thoughts:

fortran数组的强大功能之一就是可以对其进行切片.

One of the powerful things about fortran arrays is that they can be sliced.

a(:,:,3) = b(:,:,3)

是一个完全有效的语句. 如果数组是数组指针数组",则无法实现,因为沿每个轴的尺寸不一定是一致的(正是您要实现的情况).

is a perfectly valid statement. This could not be achieved if arrays were "arrays of pointers to arrays" since the dimensions along each axis would not necessarily be consistent (the very case you're trying to implement).

在C语言中,实际上没有多维数组之类的东西.您可以使用指向数组的指针数组来实现看起来相似的东西,但这实际上不是多维数组,因为它不共享公共的内存块.这可能会对性能产生影响.实际上,在HPC(许多Fortran用户花费时间的地方)中,多维C数组通常是包裹在宏中的一维数组,用于根据维度的大小来计算跨度.同样,取消引用这样的7D数组:

In C, there really is no such thing as a multidimensional array. You can implement something that looks similar using arrays of pointers to arrays, but that isn't really a multidimensional array since it doesn't share a common block of memory. This can have performance implications. In fact, in HPC (where many Fortran users spend their time), a multi-dimensional C array is often a 1D array wrapped in a macro to calculate the stride based on the size of the dimensions. Also, dereferencing a 7D array like this:

a[i][j][k][l][m][n][o]

比以下输入难得多:

a(i,j,k,l,m,n,o)

最后,您发布的解决方案与您要模拟的C代码最接近-这是怎么回事?请注意,对于您的问题陈述,可能是顺序更复杂的数据结构(如链接列表)(可以在C或Fortran中实现).当然,就性能而言,链表是最糟糕的,但是,如果这不是一个问题,它可能是正确的数据结构,可以用作购物者"来决定将更多内容添加到购物车"中,即使它不在他们带到商店的购物清单上.

Finally, the solution that you've posted is closest to the C code that you're trying to emulate -- what's wrong with it? Note that for your problem statement, a more complex data-structure (like a linked-list) might be in order (which can be implemented in C or Fortran). Of course, linked-lists are the worst as far as performance goes, but if that's not a concern, it's probably the correct data structure to use as a "shopper" can decide to add more things into their "cart", even if it wasn't on the shopping list they took to the store.

这篇关于可变大小数组的Fortran数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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