How to initialize two-dimensional arrays in Fortran

How can you do the same in Fortran for two-dimensional arrays when you wish to initialize a matrix with specific test values for mathematical purposes? (Without having to doubly index every element on separate statements) The array is either defined by

real, dimension(3, 3) :: a 
real, dimension(:), allocatable :: a 
195 1 1 silver badge 16 16 bronze badges asked Sep 14, 2010 at 11:12 Fludlu McBorry Fludlu McBorry 443 1 1 gold badge 4 4 silver badges 4 4 bronze badges

3 Answers 3

You can do that using reshape and shape intrinsics. Something like:

INTEGER, DIMENSION(3, 3) :: array array = reshape((/ 1, 2, 3, 4, 5, 6, 7, 8, 9 /), shape(array)) 

But remember the column-major order. The array will be

1 4 7 2 5 8 3 6 9 
1 2 3 4 5 6 7 8 9 

you also need transpose intrinsic:

array = transpose(reshape((/ 1, 2, 3, 4, 5, 6, 7, 8, 9 /), shape(array))) 

For more general example (allocatable 2D array with different dimensions), one needs size intrinsic:

PROGRAM main IMPLICIT NONE INTEGER, DIMENSION(:, :), ALLOCATABLE :: array ALLOCATE (array(2, 3)) array = transpose(reshape((/ 1, 2, 3, 4, 5, 6 /), & (/ size(array, 2), size(array, 1) /))) DEALLOCATE (array) END PROGRAM main 
817 5 5 silver badges 11 11 bronze badges answered Sep 14, 2010 at 11:23 8,831 6 6 gold badges 44 44 silver badges 64 64 bronze badges

1) Most compilers now accept the Fortran 2003 notation [] to initialize arrays, instead of the somewhat awkward (/ /). 2) For simple cases you can omit transpose by providing the values in the column-major order: array = reshape ( [1, 4, 7, 2, 5, 8, 3, 6, 9 ], shape (array) )

Commented Sep 14, 2010 at 13:01 I forgot to mention that we're required to work in Fortran 90. Commented Sep 14, 2010 at 17:36

For multidimensional (rank>1) arrays, the Fortran way for initialization differs from the C solution because in C multidimensional arrays are just arrays of arrays of etc.

In Fortran, each rank corresponds to a different attribute of the modified data type. But there is only one array constructor, for rank-1 arrays. From these two reasons, initialization through array constructor requires the RESHAPE intrisic function.

In addition to what has already been answered, there is a more direct way of entering the value of a matrix by row instead as by column: reshape has an optional argument ORDER which can be used to modify the order of filling the element of the multidimensional array with the entries of the array constructor.

For instance, in the case of the example in the first answer, one could write:

INTEGER, DIMENSION(3, 3) :: array=reshape( (/ 1, 2, 3, & 4, 5, 6, & 7, 8, 9 /), & shape(array), order=(/2,1/) ) 

obtaining the filling of the matrix array exactly in the order shown by the lines of code.

The array (/2, 1/) forces the column index (2) to have precedence on the row index (1) , giving the desired effect.