Changeset 2050 for trunk/LMDZ.COMMON/libf/misc
- Timestamp:
- Nov 30, 2018, 12:55:49 AM (6 years ago)
- File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/LMDZ.COMMON/libf/misc/sort_mod.F90
r2049 r2050 1 MODULE qsort_mod1 MODULE sort_mod 2 2 3 ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4 ! Quick-sort algorithm 5 ! ~~~~~~~~~~~~~~~~~~~~~ 6 ! -> Sorts an array (real only for now) y by increasing values 7 ! -> If wanted, applies the same sorting to a companion array x ( useful if you have binned xy data ) 3 ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4 ! Sorting algorithms 5 ! ~~~~~~~~~~~~~~~~~~~ 6 ! Contains quicksort (qsort) and insertion sort (isort) 7 ! -> Sorts an array (real only for now) by increasing values 8 ! -> If wanted, output indexes of permutations if you want to apply the same sorting to other arrays 9 ! ( this is quicker than having other arrays going through the whole process ) 8 10 ! 9 ! TODO : Extend interface to integers 11 ! TODO : Extend interface to integers - Enable decreasing order 10 12 ! 11 13 ! Author : J. Vatant d'Ollone - 2018 12 ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~14 ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 13 15 14 16 IMPLICIT NONE 15 17 16 18 INTERFACE qsort 17 MODULE PROCEDURE qsort_ y_r18 MODULE PROCEDURE qsort_ xy_r19 MODULE PROCEDURE qsort_r 20 MODULE PROCEDURE qsort_outp_r 19 21 END INTERFACE qsort 22 23 INTERFACE isort 24 MODULE PROCEDURE isort_r 25 MODULE PROCEDURE isort_outp_r 26 END INTERFACE isort 20 27 21 28 CONTAINS 22 29 23 RECURSIVE SUBROUTINE qsort_y_r(y,n) 30 ! 1-pivot quicksort 31 RECURSIVE SUBROUTINE qsort_r(A,n) 24 32 25 33 IMPLICIT NONE … … 27 35 ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 28 36 ! I/O 29 integer, intent(in) :: n !! Size of arrays 30 real, dimension(n), intent(inout) :: y !! Values to sort by 37 !logical, intent(in) :: o !! Order T=increasing/F=decreasing 38 integer, intent(in) :: n !! Size of array 39 real, dimension(n), intent(inout) :: A !! Array to sort 31 40 32 41 ! Local variables … … 34 43 real :: random 35 44 real :: pivot 36 real :: temp y45 real :: temp 37 46 integer :: marker 38 47 ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ … … 41 50 42 51 call random_number(random) 43 pivot = y(int(random*real(n-1))+1) ! random pivot (not best performance, but avoids worst-case)52 pivot = A(int(random*real(n-1))+1) ! random pivot (not best performance, but avoids worst-case) 44 53 left = 0 45 54 right = n + 1 … … 47 56 do while (left < right) 48 57 right = right - 1 49 do while ( y(right) > pivot)58 do while (A(right) > pivot) 50 59 right = right - 1 51 60 enddo 52 61 left = left + 1 53 do while ( y(left) < pivot)62 do while (A(left) < pivot) 54 63 left = left + 1 55 64 enddo 56 65 if (left < right) then 57 temp y = y(left)58 y(left) = y(right)59 y(right) = tempy66 temp = A(left) 67 A(left) = A(right) 68 A(right) = temp 60 69 endif 61 70 enddo … … 67 76 endif 68 77 69 call qsort( y(:marker-1), marker-1)70 call qsort( y(marker:), n-marker+1)78 call qsort(A(:marker-1), marker-1) 79 call qsort(A(marker:), n-marker+1) 71 80 72 81 endif 73 82 74 END SUBROUTINE qsort_ y_r83 END SUBROUTINE qsort_r 75 84 76 85 77 RECURSIVE SUBROUTINE qsort_xy_r(y,x,n) 86 ! 1-pivot quicksort + output array of permutations 87 RECURSIVE SUBROUTINE qsort_outp_r(A,n,P) 78 88 79 89 IMPLICIT NONE … … 81 91 ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 82 92 ! I/O 83 integer, intent(in) :: n !! Size of arrays 84 real, dimension(n), intent(inout) :: y !! Values to sort by 85 real, dimension(n), intent(inout) :: x !! Companion array that will be sorted same way as y 93 !logical, intent(in) :: o !! Order T=increasing/F=decreasing 94 integer, intent(in) :: n !! Size of array 95 integer, dimension(n), intent(inout) :: P !! Output array of permutations 96 real, dimension(n), intent(inout) :: A !! Array to sort 86 97 87 98 ! Local variables 99 integer :: i 88 100 integer :: left, right 89 101 real :: random 90 102 real :: pivot 91 real :: temp y92 real :: tempx103 real :: tempA 104 integer :: tempP 93 105 integer :: marker 94 ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 106 ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 95 107 96 108 if (n > 1) then 97 109 98 110 call random_number(random) 99 pivot = y(int(random*real(n-1))+1) ! random pivot (not best performance, but avoids worst-case)111 pivot = A(int(random*real(n-1))+1) ! random pivot (not best performance, but avoids worst-case) 100 112 left = 0 101 113 right = n + 1 … … 103 115 do while (left < right) 104 116 right = right - 1 105 do while ( y(right) > pivot)117 do while (A(right) > pivot) 106 118 right = right - 1 107 119 enddo 108 120 left = left + 1 109 do while ( y(left) < pivot)121 do while (A(left) < pivot) 110 122 left = left + 1 111 123 enddo 112 124 if (left < right) then 113 temp y = y(left)114 temp x = x(left)115 y(left) = y(right)116 x(left) = x(right)117 y(right) = tempy118 x(right) = tempx125 tempA = A(left) 126 tempP = P(left) 127 A(left) = A(right) 128 P(left) = P(right) 129 A(right) = tempA 130 P(right) = tempP 119 131 endif 120 132 enddo … … 126 138 endif 127 139 128 call qsort( y(:marker-1), x(:marker-1), marker-1)129 call qsort( y(marker:), x(marker:), n-marker+1)140 call qsort(A(:marker-1), marker-1, P(:marker-1)) 141 call qsort(A(marker:), n-marker+1, P(marker:)) 130 142 131 143 endif 132 144 133 END SUBROUTINE qsort_ xy_r145 END SUBROUTINE qsort_outp_r 134 146 135 147 136 END MODULE qsort_mod 148 ! Insertion sort 149 SUBROUTINE isort_r(A,n) 150 IMPLICIT NONE 137 151 152 INTEGER, INTENT(in) :: n !! Size of array 153 REAL, DIMENSION(n), INTENT(inout) :: A !! Array to sort 154 155 INTEGER :: i, j 156 REAL :: x 157 158 DO i = 2, n 159 x = a(i) 160 j = i - 1 161 DO WHILE (j >= 1) 162 IF (a(j) <= x) EXIT 163 a(j + 1) = a(j) 164 j = j - 1 165 ENDDO 166 a(j + 1) = x 167 ENDDO 168 END SUBROUTINE isort_r 169 170 171 ! Insertion sort + output array of permutations 172 SUBROUTINE isort_outp_r(A,n,P) 173 IMPLICIT NONE 174 175 INTEGER, INTENT(in) :: n !! Size of array 176 INTEGER, DIMENSION(n), INTENT(inout) :: P !! Output array of permutations 177 REAL, DIMENSION(n), INTENT(inout) :: A !! Array to sort 178 179 INTEGER :: i, j, px 180 REAL :: x 181 182 DO i = 2, n 183 x = a(i) 184 px = p(i) 185 j = i - 1 186 DO WHILE (j >= 1) 187 IF (a(j) <= x) EXIT 188 a(j + 1) = a(j) 189 p(j + 1) = p(j) 190 j = j - 1 191 ENDDO 192 a(j + 1) = x 193 p(j + 1) = px 194 ENDDO 195 END SUBROUTINE isort_outp_r 196 197 198 END MODULE sort_mod 199
Note: See TracChangeset
for help on using the changeset viewer.