4

Is there any existing way to emulate growing array in Fortran? Like vector in C++. I was very surprised when I haven't found anything on this subject on the Internet.

As a motivation example, suppose I compute some recurrence relation and I want to store all the intermediate numbers I get. My stopping criterion is the difference between adjacent results so I cannot know beforehand how much memory I should allocate for this.

QNA
  • 1,047
  • 2
  • 14
  • 26
  • related or possible duplicate? http://stackoverflow.com/questions/8384406/how-to-increase-array-size-on-the-fly-in-fortran – solalito Aug 04 '16 at 05:31
  • To quote an answer from the above referenced post: "Adding one element at a time by growing an array is not an efficient approach. To grow an array from N elements to N+1 in Fortran will likely mean creating a new array and copying all of the existing elements. A more appropriate data structure might be a linked list." – solalito Aug 04 '16 at 05:32
  • You've tagged as [tag:fortran90]. Do you really need to ignore changes to the language over the last 25 years? For example, the very simple `a=[a,5]` isn't F90. (Or efficient.) – francescalus Aug 04 '16 at 06:54
  • RESHAPE, UBOUND, and a few other intrinsically are your friend here. – Holmz Aug 04 '16 at 08:56
  • The smart Alec answer is MOVE_ALLOC, which is from F2003 I think. – Holmz Aug 04 '16 at 09:06
  • I can't see how RESHAPE or UBOUND can help here. Not even MOVE_ALLOC alone. The F2003 `a=[a,5]` is a simple example what can be doneeasily, but what will be slow. – Vladimir F Героям слава Aug 04 '16 at 09:58
  • @solalito Yes, that post is about implementation. I know how to implement it. I'm new to fortran so I was wondering if there an _existing_ data structure or syntax for it, maybe added in some later standard, which I don't know about, so I could avoid reinventing the wheel. – QNA Aug 04 '16 at 13:53
  • @francescalus No, I don't really have to keep to fortran90, I removed redundant tag – QNA Aug 04 '16 at 13:56

1 Answers1

10

I am sure it has been shown somewhere on this site before, but I cannot find it.

First, in Fortran 2003, you can add one element by simple

a = [a, item]

as commented by francescalus. This is likely to reallocate the array very often and will be slow.

You can keep your array to be allocated to somewhat larger size then your number of elements n. When your number of elements n grows above the size of the array size(a) you can allocate a new array larger by some factor (here 2x) and copy the old elements there. There is no realloc() in Fortran, unfortunately.

module growing_array
  implicit none

  real, allocatable :: a(:)

  integer :: n

contains

  subroutine add_item(item)
    real, allocatable :: tmp(:)
    real, intent(in) :: item

    if (n == size(a)) then
      !this statement is F2003, it can be avoided, but I don't see why in 2016
      call move_alloc(a, tmp)

      allocate(a(n*2))
      a(1:n) = tmp
    end if

    n = n + 1

    a(n) = item
  end subroutine
end module

I left out the initial allocation, it is simple enough.

It all can be put into a derived type with type-bound procedures, and use it as a data structure, but that is pure Fortran 2003 and you wanted 90. So I show Fortran 95, because Fortran 90 is flawed in many ways for allocatable arrays and is desperately obsolete and essentially dead.

  • 1
    thanks, I was hoping fortran already has it implemented so I could avoid reinventing the wheel, but the more I use fortran the more I realize: fortran doesn't like to make your life easier. – QNA Aug 04 '16 at 14:02
  • 1
    FWIW the referenced c++ vector type does something similar, allocating blocks at a time. It might be worth looking into exactly what the algorithm is. – agentp Aug 04 '16 at 14:41
  • 1
    @HighPerformanceMark Unfortunately, it's not my decision to make. Let's make a more fair comparison. C++ has wide range of different functions and data structures in standard library which doesn't prevent it from outperforming fortran in many tasks. Fortran could have the same standard library but nobody wrote it yet (to the best of my knowledge), which is why I said that fortran doesn't like to make your life easier :) – QNA Aug 04 '16 at 16:56
  • 2
    So use C++, problem solved. Do they finally introduced usable dynamically allocated contiguous 3D arrays? With any starting index? Creating such a library is not that simple it may seem and more support from the language would be necessary https://groups.google.com/forum/#!topic/comp.lang.fortran/jIVnmL9b2ZY[26-50] – Vladimir F Героям слава Aug 04 '16 at 17:14
  • @VladimirF How often do you need 3D arrays with nonstandard starting index? Anyway, it's relatively easy to implement comparing to the whole standard library. Maybe syntax won't be as pretty as in fortran but it will be useable. And I didn't say it's easy to implement standard library, but it's necessary if you want to make your language friendly and simple. – QNA Aug 04 '16 at 17:42
  • 1
    Much more often than a growing array. – Vladimir F Героям слава Aug 04 '16 at 18:11
  • In the example where IF (n==SIZE(A))... I think SIZE should be replaced with UBOUND ? – Holmz Aug 05 '16 at 12:10
  • @Holmz it doesn't matter if you start at 1. – Vladimir F Героям слава Aug 05 '16 at 12:31