2

I want to reference a 2-D array, the size of which is determined at run time, as a 1-D array without copying or mutating the original array. Since Fortran uses pointers to arrays rather than pointer arrays, direct use of a pointer doesn't work in any of the permutations I have tried. EQUIVALENCE only seems to work on arrays of constant size, and TRANSFER returns a copy. The specific ordering of the 1-D array is unimportant (i.e. [x11,x12,x13...] is as good as [x11,x21,x31...]), but when I mutate the 2-D array I would like to see the changes reflected in the 1-D array and vice versa.

Ideally I could do something like:

program arr_as_vec

    implicit none
    real, allocatable, target :: arr(:,:)
    real, pointer :: vec(:)
    integer :: dim1, dim2 ! would really be determined at runtime

    dim1 = 3; dim2 = 5
    allocate(arr(dim1,dim2))
    call something_like_equivalence(arr, vec)

    arr(1,1) = 1
    arr(dim1,dim2) = 2
    print *, vec(1) ! should give 1
    print *, vec(dim1*dim2) ! should give 2

end program arr_as_vec

Is this possible?

  • 2
    You may find [some of these techniques](https://stackoverflow.com/q/5406016/3157076) useful. Especially remapping. – francescalus Jan 15 '18 at 23:09
  • @francescalus I read that, but get an error when using `ptr(1:n,1:n) => vector`. I did figure out how to do it, though, and feel as sheepish as the solution is simple. – Michael Greenburg Jan 15 '18 at 23:31
  • 1
    @MichaelGreenburg I've used a similar approach in your answer before, but now doesn't this `vec(1:size(arr)) => arr` work? (though `vec => arr` gives an error for me) – roygvib Jan 16 '18 at 05:23

1 Answers1

0

Using pointer remapping, the following works as expected with gfortran 5.4.0 (EDITED due to help from francescalus, roygvib, and VladamirF):

program arr_as_vec

    implicit none
    real, allocatable, target :: arr(:,:)
    real, pointer :: vec(:)
    integer :: dim1, dim2 ! would really be determined at runtime

    dim1 = 3; dim2 = 5
    allocate(arr(dim1,dim2))
    vec(1:dim1*dim2) => arr

    arr(1,1) = 1
    arr(dim1,dim2) = 2
    print *, vec(1) ! should give 1
    print *, vec(dim1*dim2) ! should give 2
    print *, size(vec) ! should give 15
    vec(1) = 3
    print *, arr(1,1) ! should be 3

end program arr_as_vec