0

I want to store something in 2 dimensional array in my code and later want to scan that array. There are N_{1} rows (number of first indices, say i) in the array. However, for a given value of i, number of j values is not fixed though I know the maximum possible value of j (say that it is N_{2}).

I can of course create array of size (N_{1},N_{2}) to store my data. This, however seems wastage of space because my N_{2} values fluctuate a lot and the total number of elements in my array is also very large. Is is possible to create a 2D array that can have different number of j values depending on i value? Alternatively, even if I could create many-many 1D arrays by a single Fortran command and allocate them properly, that is also OK with me.

Peaceful
  • 4,920
  • 15
  • 54
  • 79
  • 3
    Are you after [ragged arrays](http://stackoverflow.com/q/18316592/3157076)? Either way, you're likely looking at more than one statement. – francescalus Dec 06 '14 at 13:28
  • You should look into the `ALLOCATABLE` keyword. – Joel DeWitt Dec 06 '14 at 16:17
  • Well, ragged array seems to be useful here. Allocatable doesn't help of course. It works for regular arrays only as far as I know. – Peaceful Dec 06 '14 at 18:22
  • 2
    Use the ragged array type suggested by @francescalus, write an appropriate initialization routine, put it all in a module and call it good. Your one line allocation of many arrays can be done by calling your appropriately written initialization routine. – Doug Lipinski Dec 06 '14 at 19:48

1 Answers1

3

As you suggest that the answer to another question, looking at ragged arrays may be what you want, I'll briefly mention a usability extension to that answer (hinted at in comment by Doug Lipinski).

For a base type, representing the variable-length dimension, given by High Performance Mark

type :: vector
    integer, dimension(:), allocatable :: elements
end type vector

and a type for an array of those

type :: ragged_array
    type(vector), dimension(:), allocatable :: vectors
end type ragged_array

one has the allocation steps

type(ragged_array) :: ragarr

allocate(ragarr%vectors(5))
allocate(ragarr%vectors(1)%elements(3))
! etc.

[Alternatively, one may be tempted to just have an array of type(vector).]

For the usability aspect one could create a structure constructor which does the numerous allocations, or even rely on automatic allocation for the variable length components.

In the latter case, which makes sense if the values, not just the extents, are known at creation.

allocate(ragarr%vectors(5))
ragarr%vectors(1)%elements = [1, 6, 13]
! etc.

For the former case, something like

module ragged

  implicit none

  type :: vector
      integer, dimension(:), allocatable :: elements
  end type vector

  type :: ragged_array
      type(vector), dimension(:), allocatable :: vectors
  end type ragged_array

  interface ragged_array
      module procedure ragged_constructor
  end interface ragged_array

contains

  function ragged_constructor(sizes) result(ra)
      integer, intent(in) :: sizes(:)
      type(ragged_array) ra
      integer i

      allocate(ra%vectors(SIZE(sizes)))
      do i=1,SIZE(sizes)
          allocate(ra%vectors(i)%elements(sizes(i)))
      end do

  end function ragged_constructor

end module ragged

program test

    use ragged
    implicit none

    type(ragged_array) :: ra

    ra = ragged_array([3,4,6,1,12])

end program
Community
  • 1
  • 1
francescalus
  • 30,576
  • 16
  • 61
  • 96