I want to be able to have a large master array and refer to different parts of it using sub arrays. At the moment I'm using offset indices to do this, but it can get very complicated doing it this way.
Can I have a master array of dimension(9), and 3 sub arrays of dimension(3) such that sub_array1 points to the first 3 elements of the master_array, sub_array2 points to the next 3 elements and sub_array3 points to the last 3 elements?
For example, the arrays would be defined like so:
integer, dimension(9) :: master_array
integer, dimension(3) :: sub_array1, sub_array2, sub_array3
The relationship between the arrays would be:
sub_array1(1) -> master_array(1)
sub_array1(2) -> master_array(2)
sub_array1(3) -> master_array(3)
sub_array2(1) -> master_array(4)
sub_array2(2) -> master_array(5)
sub_array2(3) -> master_array(6)
sub_array3(1) -> master_array(7)
sub_array3(2) -> master_array(8)
sub_array3(3) -> master_array(9)
Furthermore, is it possible to have mixed datatypes so that I have one sub array of reals within a larger master array of integers?
Thanks in advance for the help
In simple words, array names are converted to pointers. That's the reason why you can use pointers to access elements of arrays. However, you should remember that pointers and arrays are not the same. There are a few cases where array names don't decay to pointers.
However, in Fortran, a pointer is a data object that has more functionalities than just storing the memory address. It contains more information about a particular object, like type, rank, extents, and memory address. A pointer is associated with a target by allocation or pointer assignment.
Fortran stores higher dimensional arrays as a contiguous sequence of elements. It is important to know that 2-dimensional arrays are stored by column. So in the above example, array element (1,2) will follow element (3,1). Then follows the rest of the second column, thereafter the third column, and so on.
Yes, you can use absolutely use pointers to point to subregions of an array. This can be very handy in a lot of situations, such as for stencil calculations for PDEs:
program pointerviews
real, dimension(10), target :: alldata
real, dimension(:), pointer :: left
real, dimension(:), pointer :: centre
real, dimension(:), pointer :: right
alldata = (/ (i, i=1,10) /)
left => alldata(1:8)
right => alldata(3:10)
centre=> alldata(2:9)
print *, alldata
print *, left
print *, centre
print *, right
print *, (left - 2*centre + right)
end program pointerviews
Array pointers in FORTRAN are more than just an address, they contain array size, stride, and type information, too. So you can do even crazier things like this (if you're used to C pointers) and include strides:
program pointerviews2
real, dimension(10), target :: alldata
real, dimension(:), pointer :: left
real, dimension(:), pointer :: centre
real, dimension(:), pointer :: right
alldata = (/ (i, i=1,10) /)
left => alldata(1:8:2)
right => alldata(3:10:2)
centre=> alldata(2:9:2)
print *, alldata
print *, left
print *, centre
print *, right
print *, 'Changing alldata(4) = 9999'
alldata(4) = 9999.
print *, alldata
print *, left
print *, centre
print *, right
end program pointerviews2
You cannot, however, have regions of an array which are of a different type than the rest of the data, by definition. You'll have to use derived types, or polymorphism, if you want a variable which contains data of several types.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With