Search code examples
fortranfortran90fortran77

Looking for a more concise way of writing a relatively common loop?


Is there a more concise way of writing this relatively common type of loop,

70  M=NTOC-N
    L=0
    DO 100 I=M,NTOC
    L=L+1
    X(L)=XI(I)
100 Y(L)=YI(I)

Without going into definitions of indexes, what it does is it copies the contents of arrays XI, YI from index M to NTOC to arrays X, Y indexes 1 to ... (NTOC-M) ... how many is needed.

While restructuring some older code, I noticed I had a large number of this kind of loops, and while I probably didn't know better at the time, I was wondering is there now a more concise way of writing this to aide code legibility / readability? While depending a lot on loops, I know Fortran nowadays has excellent support for all kinds of array operations, so if someone knows a way which they believe could be more legible, I would be very grateful on all suggestions!


Solution

  • Assuming n is positive, over the course of the loop i takes the values m, m+1, ..., ntoc and so the elements of xi chosen are, in order, xi(m), xi(m+1), ..., xi(ntoc). The elements of yi are similar.

    In terms of an array section, xi(m:ntoc) represents the same selection of elements.

    Similarly, the elements of x on the left-hand side are x(1), x(2), ..., x(ntoc-m+1) (=x(n+1)). As an array section, x(1:n+1) represents the same elements.

    That means:

    x(1:n+1)=xi(ntoc-n:ntoc)   ! Replacing m with its value
    y(1:n+1)=yi(ntoc-n:ntoc)
    

    And if the bounds are x and y are 1 and n+1, or the arrays are allocatable, then the whole arrays x and y could be used on the left-hand sides.

    For n zero or negative the array section will safely select the same elements as the loop (one or none).

    If you're going to use i and l outside that fragment then you'll of course have to set those manually (and don't forgot that i will take the value ntoc+1).

    Finally, if you want more incentive to get rid of that loop: note that non-block do constructs like this one are deleted by Fortran 2015.