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.

8
  • related or possible duplicate? stackoverflow.com/questions/8384406/… Commented Aug 4, 2016 at 5: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." Commented Aug 4, 2016 at 5:32
  • You've tagged as 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.) Commented Aug 4, 2016 at 6:54
  • RESHAPE, UBOUND, and a few other intrinsically are your friend here. Commented Aug 4, 2016 at 8:56
  • The smart Alec answer is MOVE_ALLOC, which is from F2003 I think. Commented Aug 4, 2016 at 9:06

1 Answer 1

11

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.

Sign up to request clarification or add additional context in comments.

8 Comments

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.
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.
@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 :)
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 groups.google.com/forum/#!topic/comp.lang.fortran/…
Much more often than a growing array.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.