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?

3
  • 2
    You may find some of these techniques useful. Especially remapping. Commented Jan 15, 2018 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. Commented Jan 15, 2018 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) Commented Jan 16, 2018 at 5:23

1 Answer 1

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
Sign up to request clarification or add additional context in comments.

3 Comments

This is really unnecessary complicated. Have you read the link stackoverflow.com/questions/48271556/… and searched for pointer remapping? That question could even be a duplicate of your's.
@VladimirF upon switching compilers (to gfortran 5.4.0), the remapping works perfectly. Thank you!
I will close the question and point it to the other one. You can still keep it, don't delete it. Closing is not the same as deleting.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.