I revise my posted question. Here is my Fortran code.
line 1 PROGRAM COMPA
line 2 IMPLICIT NONE
line 3
line 4 INTEGER, PARAMETER :: dp = SELECTED_REAL_KIND(15,14)
line 5 INTEGER :: i, j, k, l
line 6 REAL (KIND=dp) :: ap(116,6), lr(3,3), pl(3), ns(2,116)
line 7
line 8 OPEN (UNIT=3, FILE='data.dat', STATUS='OLD')
line 9 READ (UNIT=3, FMT=*)
line 10 READ (UNIT=3, FMT=*)
line 11 DO i = 1, 3, 1
line 12 READ (UNIT=3, FMT=*) pl
line 13 lr(i,:) = pl
line 14 END DO
line 15 READ (UNIT=3, FMT=*)
line 16 DO i = 1, 116, 1
line 17 READ (UNIT=3, FMT=*) pl
line 18 ap(i,4:6) = pl
line 19 ns(:,i) = i
line 20 END DO
line 21
line 22 DO i = 1, 116, 1
line 23 ap(i,1) = ap(i,4)*lr(1,1)+ap(i,5)*lr(2,1)+ap(i,6)*lr(3,1)
line 24 ap(i,2) = ap(i,4)*lr(1,2)+ap(i,5)*lr(2,2)+ap(i,6)*lr(3,2)
line 25 ap(i,3) = ap(i,4)*lr(1,3)+ap(i,5)*lr(2,3)+ap(i,6)*lr(3,3)
line 26 END DO
line 27
line 28 DO i = 2, 116, 1
line 29 l = i
line 30 DO j = 1, i-1, 1
line 31 IF ((ap(l,1) < ap(j,1)) .OR. &
line 32 ((ap(l,1) == ap(j,1)) .AND. (ap(l,2) < ap(j,2))) .OR. &
line 33 ((ap(l,1) < ap(j,1)) .AND. (ap(l,2) == ap(j,2)) .AND. &
line 34 (ap(l,3) < ap(j,3)))) THEN
line 35 k = ns(1,i)
line 36 ns(1,j+1:i) = ns(1,j:i-1)
line 37 ns(1,j) = k
line 38 l = j
line 39 END IF
line 40 END DO
line 41 END DO
line 42
line 43 OPEN (UNIT=4, FILE='compare.dat', STATUS='UNKNOWN')
line 44 DO i = 1, 116, 1
line 45 DO j = 1, 116, 1
line 46 IF (ns(1,j) == i) WRITE (UNIT=4, FMT=*) ns(:,j), ap(j,1:3)
line 47 END DO
line 48 END DO
line 49
line 50 CLOSE (UNIT=3)
line 51 CLOSE (UNIT=4)
line 52 STOP
line 53 END PROGRAM COMPA
My code reads the following data.dat file content. and ap(i,4:6) stores the original data from the file; while, ap(i,1:3) stores the data after processing ap(i,4:6).
I want to re-organise the line number for each row, based on the ascending sequence for the 1st value in each row. If the 1st value is same in two or more rows; then, take the 2nd value for the ascending re-organising sequence. If the 2nd value is same in two or more rows; then, take the 3rd value for the ascending re-organising sequence.
Here is the data.dat file.
116
Parameter
0.2951429939E+02 0.0000000000E+00 0.0000000000E+00
0.0000000000E+00 0.1500000000E+02 0.0000000000E+00
0.0000000000E+00 0.0000000000E+00 0.2510000038E+02
Parameter
0.000000000 0.500000000 0.300000012
0.041669998 0.500000000 0.328289986
0.041669998 0.500000000 0.384860009
0.000000000 0.500000000 0.413150012
0.000000000 0.500000000 0.469720006
0.041669998 0.500000000 0.498010010
0.041669998 0.500000000 0.554579973
0.000000000 0.500000000 0.582870007
0.083329998 0.500000000 0.300000012
0.125000000 0.500000000 0.328289986
0.125000000 0.500000000 0.384860009
0.083329998 0.500000000 0.413150012
0.083329998 0.500000000 0.469720006
...
Here is the compare.dat file, which was written by the code for the re-organised data.
1.0000000000000000 1.0000000000000000 0.0000000000000000 7.5000000000000000 7.5300004152000044
2.0000000000000000 7.0000000000000000 1.2298607965527013 7.5000000000000000 13.919957533040389
3.0000000000000000 8.0000000000000000 0.0000000000000000 7.5000000000000000 14.630037397190604
4.0000000000000000 6.0000000000000000 1.2298607965527013 7.5000000000000000 12.500051440243805
5.0000000000000000 5.0000000000000000 0.0000000000000000 7.5000000000000000 11.789972329093603
6.0000000000000000 13.000000000000000 2.4594265091401013 7.5000000000000000 11.789972329093603
7.0000000000000000 16.000000000000000 2.4594265091401013 7.5000000000000000 14.630037397190604
8.0000000000000000 4.0000000000000000 0.0000000000000000 7.5000000000000000 10.370065458197006
9.0000000000000000 21.000000000000000 4.9191481317598029 7.5000000000000000 11.789972329093603
10.000000000000000 102.00000000000000 15.042847316209118 7.5000000000000000 14.464879495090205
11.000000000000000 114.00000000000000 13.527288986990197 7.5000000000000000 13.589893105343398
12.000000000000000 91.000000000000000 0.0000000000000000 7.5000000000000000 6.4399073735966041
13.000000000000000 69.000000000000000 23.365586106424487 7.5000000000000000 9.6599863721468040
14.000000000000000 83.000000000000000 27.054873530174486 7.5000000000000000 7.5300004152000044
15.000000000000000 84.000000000000000 28.284437826075518 7.5000000000000000 8.2400787733501950
16.000000000000000 24.000000000000000 4.9191481317598029 7.5000000000000000 14.630037397190604
17.000000000000000 104.00000000000000 17.216575554825518 7.5000000000000000 15.719879815290209
18.000000000000000 89.000000000000000 28.284437826075518 7.5000000000000000 13.919957533040389
19.000000000000000 64.000000000000000 20.905862978575517 7.5000000000000000 12.500051440243805
20.000000000000000 36.000000000000000 9.8380015632401978 7.5000000000000000 10.370065458197006
21.000000000000000 80.000000000000000 25.825011966250003 7.5000000000000000 12.500051440243805
Obviously, this re-organisation is wrong because the row was not written based on the ascending order.
Would anyone please give me some suggestions on what is wrong with my code? Thank you very much.
First for code clarity let's define a utility function tells if a row is "smaller" or not compared to another row (because it uses assumed shape arguments, this function must be in a module, or in the contain
section of the main program):
logical function is_smaller(rowa,rowb) result(s)
real(dp), intent(in) :: rowa(:), rowb(:)
s = .false.
if (rowa(1) < rowb(1)) then
s = .true.
else if (rowa(1) == rowb(1)) then
if (rowa(2) < rowb(2)) then
s = .true.
else if (rowa(2) == rowb(2)) then
if (rowa(3) < rowb(3)) s= .true.
end if
end if
end function
Then let's use it with an insertion sort algorithm, which is is fine for such a number of elements to sort. For code clarity again we move the data instead of using indexes (indexes would be more efficient).
real(dp) :: tmp(6)
...
do i = 2, 116
! the first (i-1) rows are sorted, we are now looking at row i
do j = 1, i-1
if (is_smaller(ap(i,:),ap(j,:))) then
! insertion of row i at position j
tmp(:) = ap(i,:)
ap(j+1:i,:) = ap(j:i-1,:)
ap(j,:) = tmp(:)
exit
end if
end do
end do