2

Heroes the new code I used. I have tried this, and it works if I have n declared first, which is not what I want. I need to know the total number of rows (n) and use that number afterward in my simulation. However, in variable declaration I need to have the diminution of my xy(n) before reading the data and if I do that, the code does not run.

the data file is two column of randomly simulated normal data

lets say something like this

1  3
2  4
3   6
4  8
5   9
6  8
7   1
8  9
99  88

I tried the following code to determine n but it did not work!

     program reading

implicit none
integer,allocatable :: a(:,:)
  integer :: pair(2)
  integer :: unit, n, io,k
!!!variable declaration 

 real, dimension(1:n)::x,y
 integer:: T, I1, I2, I3, i, j, dist
open(2, file = 'xyBVNData_R.txt', status = 'old', action = 'read')


n = 0 
DO
  READ(2,*,iostat=io)
  IF (io/=0) EXIT
  n = n + 1
END DO
CLOSE (2)
  print*, n



 DO i=1,n!!!
  DO j=1,n!!
 dist=0.0
 DIST = dist+(sqrt((x(i)-x(j))**2 + (y(i)-y(j))**2))

 ENDDO
     ENDDO

 !!! writing and saving 
 Do i= 1, n 
  write(*,*) i, x(i)
 ENDDO
end program reading
sxq2221
  • 57
  • 1
  • 6
  • Have you tried to read this site? There are many similar questions and answers here. And BTW *"I do not know how what to do to let fortran figur out how many number of rows after reading the data frame."* is not a question, it is a statement, even if you put a questionmark at the end. – Vladimir F Героям слава May 30 '17 at 07:53
  • 1
    There are more duplicates than just the one I found first (it is just a coincidence that it contains my answer). If it does not suit you we need the details of your datafile and your code to be able to give a detailed answer. – Vladimir F Героям слава May 30 '17 at 08:00
  • @VladimirF Thank you very much. I edited my question. The code you mentioned is to read line by line the data, but What I want here is something slightely different. – sxq2221 May 30 '17 at 19:59
  • Well the solution is exactly there in my answer, but if you want to argue that the question is not an exact duplicate then it maybe isn't. **Never** use *"it did not work"* It does not tell us anything useful. Tell us what happened. Error messages? Which exact messages? Wrong results? Which exact results? **How does the datafile look like?** Which number did the your line `print*,n` print? – Vladimir F Героям слава May 30 '17 at 20:06
  • Also, **do not** use unit number less then 10. Some unit numbers are reserved. Do not use unit number 2. Use something higher than 10. – Vladimir F Героям слава May 30 '17 at 20:12
  • Hello and I am sorry if my question seems very silly. I am less than bigger in Fortran. thank you for your patience. .I updated the code. See please the dimension of xy. my issue, If I declared the dimension of xy as a known number, xy(194), the code works fine. However, in my case I need the xy to have the n dimension, xy(n), and n depends on the file itself. The code just does not run. I am not sure if I am clear enough. – sxq2221 May 30 '17 at 21:47
  • Did it compile at all? Any error message? There should be an error message. – Vladimir F Героям слава May 30 '17 at 21:58
  • @VladimirF yes it compiles now. – sxq2221 May 30 '17 at 22:03
  • But onl with x an y fixed size. Just make them allocatable. – Vladimir F Героям слава May 30 '17 at 22:11
  • Still tell us what happens when you run it. Is anything printed? – Vladimir F Героям слава May 30 '17 at 22:13
  • you never read or set x or y. What result are you expecting? – agentp May 31 '17 at 00:01
  • @VladimirF how to make them allocatable? no nothing is printed at all if I put real, dimension(1:n)::x,y.If I put, however, real, dimension(1:9)::x,y then the distance is printed. – sxq2221 May 31 '17 at 00:16
  • If you put `dimension(1:n)` then a compiler *must* find an error because `n` is not a constant. If your code is the real code than itcannot compile with `dimension(1:n)`. If it is not your real code, you must show your real code. – Vladimir F Героям слава May 31 '17 at 03:03
  • first of all, thank you for your patience really. You are right. When I put dimension(1:n), the code does not run. I can put the real code.Is it possible to delete the code afterward, because it is confidential for my research and I cannot leave it online. Thank you very much. – sxq2221 May 31 '17 at 05:15
  • You now have an answer from M. Chinoune. I hope it is a sufficient. Just about the *real* code. You don't have to copy the full production research code here. Not at all! It would probably bee too long anyway. But **you should** put here the *real* test code you are trying to compile. See [mcve]. We want a small piece of code which you actually tried to compile and tested. – Vladimir F Героям слава May 31 '17 at 08:16

1 Answers1

6

You can't declare variables with unknown dimension "dimension(1:n)".

This program first reads the file to determine the number of rows:

program reading
  implicit none
!  variable declaration 
  real, dimension(:) ,allocatable :: x ,y 
  real :: dist
  integer:: i, j ,n ,io

  open(2, file = 'xyBVNData_R.txt', status = 'old', action = 'read')

  n = 0 
  DO
    READ(2,*,iostat=io)
    IF (io/=0) EXIT
    n = n + 1
  END DO
  print*, n

  allocate( x(n) ,y(n) )
  rewind(2)
  DO i =1,n
    READ(2,*) x(i),y(i)
  END DO

  dist=0.0
  DO i=1,n
    DO j=1,n
      dist = dist + sqrt( (x(i)-x(j))**2 + (y(i)-y(j))**2 )
    END DO
  END DO

  ! writing and saving 
  DO i= 1, n 
    write(*,*) i, x(i)
  END DO

end program reading

Another alternative (Fortran 2003), it reallocates the arrays x and y by adding the new element when a new line is read:

program reading
  implicit none
!  variable declaration 
  real, dimension(:) ,allocatable :: x ,y 
  real :: dist ,x_tmp ,y_tmp
  integer:: i, j ,n ,io

  open(2, file = 'xyBVNData_R.txt', status = 'old', action = 'read')

  n = 0 
  allocate( x(0) ,y(0) )
  DO
    READ(2,*,iostat=io) x_tmp,y_tmp
    x = [x,x_tmp]
    y = [y,y_tmp]
    IF (io/=0) EXIT
    n = n + 1
  END DO
  print*, n

  dist=0.0
  DO i=1,n
    DO j=1,n
      dist = dist + sqrt( (x(i)-x(j))**2 + (y(i)-y(j))**2 )
    END DO
  END DO

  ! writing and saving 
  DO i= 1, n 
    write(*,*) i, x(i)
  END DO

end program reading
M. Chinoune
  • 409
  • 5
  • 10
  • Thank you M. C, thank you thank you very much. This actually works perfectly, and this is what I need. cheers – sxq2221 May 31 '17 at 08:28
  • May I ask what this piece of code mean? {READ(2,*,iostat=io) IF (io/=0) EXIT} . Thank you very much – sxq2221 May 31 '17 at 09:34
  • It reads the line without reading data, if the READ() operation succeeds (io=0) then it jump to the next line or (io/=0) it exists from the loop. – M. Chinoune May 31 '17 at 10:35
  • Great. Thank you for the second code. I like it better. – sxq2221 Jun 01 '17 at 06:51
  • @M. Chinoune do you have any experience how much slower the second code is due to the automatic reallocation? But then you save time only reading once, I wonder what the tradeoff is. – Mark S Jun 08 '17 at 05:57
  • 1
    I haven't any experience, I know that automatic reallocation make programs run slow but I think i/o is also slow. It is not recommended to use automatic reallocation in a part of code that called many times (>10000). – M. Chinoune Jun 08 '17 at 09:28
  • I didn't know that array sizes could be changed in run-time! – Peaceful Oct 06 '21 at 08:23
  • the first method is not reliable if you have multiple blank lines after the actual data in the file. – Youjun Hu Apr 06 '23 at 13:54