2

I want an array to remove all the rows after a certain index value from an array in Fortran. That means that if the size of the array initially is p, it should become q, where q is the index after which everything is to be removed.

Here is the relevant bit of code:

real(8), allocatable :: circlesx(:),circlesy(:)
allocate(circlesx(n**2-n))
allocate(circlesy(n**2-n))

do i=1,n-1
    do j=i+1,n
        call intersect2circles(stlo(i),stla(i),distance(i),stlo(j),stla(j),distance(j),ax,ay,bx,by,flag)
        if (flag==0) then
            circlesx(k)=ax
            circlesy(k)=ay
            circlesx(k+1)=bx
            circlesy(k+1)=by
            k=k+2
        endif
    enddo
enddo

The flag basically checks if two circles intersect or not. So if there is no intersection, no values are assigned to the arrays circlesx and circlesy. The size of the arrays which I am allocating at first is the maximum number of points of intersection of n circles = n^2-n. I get a segmentation fault if I don't allocate them.

Reshape also didn't work, although I might have done something wrong there. This gave an unclassifiable statement error:-

reshape(circlesx,[ n**2-n-1 ])

I want the size of the circles arrays to change to k-2 after the loops are done

So what I need is, if n=2, so circlesx and circlesy have a size of 2, then,

circlesx=[0,0]
.
.
some calculations
.
.
circlesx=[1.2,0] ! only one value has been allocated
.
.
reshape the array accordingly
.
.
circlesx=[1.2]

Is there any way to do this in Fortran? I am using an f90 file extension and using gfortran v7.3.0

Yuki.kuroshita
  • 759
  • 9
  • 29
  • 3
    Is there a reason why something like `a=a(:q)` doesn't suit? – francescalus Nov 21 '18 at 20:12
  • 1
    These are the days where my understanding of Fortran is thoroughly blown. I've been using temporary arrays and `move_alloc` to resize arrays, and now I realise that it's just so simple to resize allocatable arrays. Since when is that standard? – chw21 Nov 21 '18 at 23:10
  • Since `move_alloc` also became standard: Fortran2003 – Rodrigo Rodrigues Nov 22 '18 at 02:28
  • By the way, take this as an opportunity for a fresh new start of your Fortran practices: abandon [`real(8)`notation](https://stackoverflow.com/questions/3170239/fortran-integer4-vs-integer4-vs-integerkind-4) and embrace standardization & portability. – Rodrigo Rodrigues Nov 22 '18 at 02:38
  • I think you are right. I learnt fortran by looking at other people's codes. I do need to read a book on fortran to get a better idea of what all I am doing wrong. – Yuki.kuroshita Nov 22 '18 at 03:59
  • I apologise for such a late reply, I had to go to sleep, but a=a(:q) as you suggested, is it compatible with Fortran 95? Because I have to work with a lot of old scripts, this one must fit in perfectly with the other ones. – Yuki.kuroshita Nov 22 '18 at 04:03
  • It will be compiled without issues with your gfortran version. Once compiled, any Fortran code is compatible with any other newert/older fortran code if the arguments match. – Rodrigo Rodrigues Nov 22 '18 at 05:33
  • See [this question](https://stackoverflow.com/q/42140832/3157076) for details on F95/F2003. – francescalus Nov 22 '18 at 08:41

1 Answers1

5

Questions around here about dynamic resizing of an array generally care about enlargening the array. That is the harder problem.1

However, the fundamental considerations are much the same. Consider

integer, allocatable :: arr(:)
allocate(arr(3))
arr = [1, 2, 3]

end

With intrinsic assignment we see from elsewhere that we could just write

integer, allocatable :: arr(:)
arr = [1, 2, 3]

end

and have arr allocated to the correct shape as part of the assignment.

We've seen this to: enlarge an array

arr = [arr, 4]

remove "bad values":

arr = PACK(arr, arr>1.and.arr<4)

Selecting just the first few elements is as simple as

arr = arr(:q)

The days where compilers require special flags to compile such code correct are slowly passing, but do (especially if using an old version) check your compiler documentation for how to ensure automatic allocation happens on intrinsic assignment.


1 Even in the days without dynamic memory allocation, one handled "shorter" arrays simply. Take a static-sized array as large as you'll ever need and do some bookkeeping around how many elements are used. In modern code you may see such artefacts when using old libraries.

francescalus
  • 30,576
  • 16
  • 61
  • 96
  • Thanks for the explanation. I have seen a lot of huge sized arrays in some codes yeah. I even somtimes have to work with fortran 77 code. I hope to update all the old code one day if possible, but with a huge repository of outdated codes, I don't realise what to do when. – Yuki.kuroshita Nov 22 '18 at 08:55