SABER
tools_qsort.F90
Go to the documentation of this file.
1 # 1 "/Users/miesch/JEDI/code/working_copy/public/fv3-bundle/saber/src/saber/external/tools_qsort.fypp"
2 # 1 "/Users/miesch/JEDI/code/working_copy/public/fv3-bundle/saber/src/saber/external/../generics.fypp" 1
3 !----------------------------------------------------------------------
4 ! Header: generics
5 !> Generic ranks, dimensions and types
6 ! Author: Benjamin Menetrier
7 ! Licensing: this code is distributed under the CeCILL-C license
8 ! Copyright 2015-... UCAR, CERFACS, METEO-FRANCE and IRIT
9 !----------------------------------------------------------------------
10 
11 # 56 "/Users/miesch/JEDI/code/working_copy/public/fv3-bundle/saber/src/saber/external/../generics.fypp"
12 # 2 "/Users/miesch/JEDI/code/working_copy/public/fv3-bundle/saber/src/saber/external/tools_qsort.fypp" 2
13 # 1 "/Users/miesch/JEDI/code/working_copy/public/fv3-bundle/saber/src/saber/external/../instrumentation.fypp" 1
14 # 1 "/Users/miesch/JEDI/code/working_copy/public/fv3-bundle/saber/src/saber/external/../subr_list.fypp" 1
15 !----------------------------------------------------------------------
16 ! Header: subr_list
17 !> Subroutines/functions list
18 ! Author: Benjamin Menetrier
19 ! Licensing: this code is distributed under the CeCILL-C license
20 ! Copyright 2015-... UCAR, CERFACS, METEO-FRANCE and IRIT
21 !----------------------------------------------------------------------
22 
23 # 726 "/Users/miesch/JEDI/code/working_copy/public/fv3-bundle/saber/src/saber/external/../subr_list.fypp"
24 # 2 "/Users/miesch/JEDI/code/working_copy/public/fv3-bundle/saber/src/saber/external/../instrumentation.fypp" 2
25 !----------------------------------------------------------------------
26 ! Header: instrumentation
27 !> Instrumentation functions
28 ! Author: Benjamin Menetrier
29 ! Licensing: this code is distributed under the CeCILL-C license
30 ! Copyright 2015-... UCAR, CERFACS, METEO-FRANCE and IRIT
31 !----------------------------------------------------------------------
32 
33 # 112 "/Users/miesch/JEDI/code/working_copy/public/fv3-bundle/saber/src/saber/external/../instrumentation.fypp"
34 # 3 "/Users/miesch/JEDI/code/working_copy/public/fv3-bundle/saber/src/saber/external/tools_qsort.fypp" 2
35 !----------------------------------------------------------------------
36 ! Module: tools_qsort
37 !> Qsort routines
38 ! Source: http://jblevins.org/mirror/amiller/qsort.f90
39 ! Author: Brainerd, W.S., Goldberg, C.H. & Adams, J.C. (1990) "Programmer's Guide to Fortran 90", McGraw-Hill ISBN 0-07-000248-7, pages 149-150.
40 ! Original licensing: none
41 ! Modified by Alan Miller
42 ! Modified by Benjamin Menetrier for BUMP
43 ! Licensing: this code is distributed under the CeCILL-C license
44 ! Copyright 2015-... UCAR, CERFACS, METEO-FRANCE and IRIT
45 !----------------------------------------------------------------------
47 
49 use tools_repro, only: inf,sup
50 
51 
52 implicit none
53 
54 interface qsort
55 # 24 "/Users/miesch/JEDI/code/working_copy/public/fv3-bundle/saber/src/saber/external/tools_qsort.fypp"
56  module procedure qsort_qsort_int
57 # 24 "/Users/miesch/JEDI/code/working_copy/public/fv3-bundle/saber/src/saber/external/tools_qsort.fypp"
58  module procedure qsort_qsort_real
59 # 26 "/Users/miesch/JEDI/code/working_copy/public/fv3-bundle/saber/src/saber/external/tools_qsort.fypp"
60 end interface
61 interface quick_sort
62 # 29 "/Users/miesch/JEDI/code/working_copy/public/fv3-bundle/saber/src/saber/external/tools_qsort.fypp"
63  module procedure qsort_quick_sort_int
64 # 29 "/Users/miesch/JEDI/code/working_copy/public/fv3-bundle/saber/src/saber/external/tools_qsort.fypp"
65  module procedure qsort_quick_sort_real
66 # 31 "/Users/miesch/JEDI/code/working_copy/public/fv3-bundle/saber/src/saber/external/tools_qsort.fypp"
67 end interface
69 # 34 "/Users/miesch/JEDI/code/working_copy/public/fv3-bundle/saber/src/saber/external/tools_qsort.fypp"
70  module procedure qsort_interchange_sort_int
71 # 34 "/Users/miesch/JEDI/code/working_copy/public/fv3-bundle/saber/src/saber/external/tools_qsort.fypp"
72  module procedure qsort_interchange_sort_real
73 # 36 "/Users/miesch/JEDI/code/working_copy/public/fv3-bundle/saber/src/saber/external/tools_qsort.fypp"
74 end interface
75 
76 private
77 public :: qsort
78 
79 contains
80 
81 # 44 "/Users/miesch/JEDI/code/working_copy/public/fv3-bundle/saber/src/saber/external/tools_qsort.fypp"
82 !----------------------------------------------------------------------
83 ! Subroutine: qsort_qsort_int
84 !> Sort a subvector
85 !----------------------------------------------------------------------
86 recursive subroutine qsort_qsort_int(n,list,order)
87 
88 implicit none
89 
90 ! Passed variables
91 integer, intent(in) :: n !< Input vector size
92 integer(kind_int),intent(inout) :: list(n) !< Vector to sort
93 integer,intent(inout),optional :: order(n) !< Positions of the elements in the original order
94 
95 ! Local variable
96 integer :: i
97 integer :: lorder(n)
98 
99 do i=1,n
100  lorder(i) = i
101 end do
102 
103 call quick_sort(n,1,n,list,lorder)
104 
105 if (present(order)) order = lorder
106 
107 end subroutine qsort_qsort_int
108 # 44 "/Users/miesch/JEDI/code/working_copy/public/fv3-bundle/saber/src/saber/external/tools_qsort.fypp"
109 !----------------------------------------------------------------------
110 ! Subroutine: qsort_qsort_real
111 !> Sort a subvector
112 !----------------------------------------------------------------------
113 recursive subroutine qsort_qsort_real(n,list,order)
114 
115 implicit none
116 
117 ! Passed variables
118 integer, intent(in) :: n !< Input vector size
119 real(kind_real),intent(inout) :: list(n) !< Vector to sort
120 integer,intent(inout),optional :: order(n) !< Positions of the elements in the original order
121 
122 ! Local variable
123 integer :: i
124 integer :: lorder(n)
125 
126 do i=1,n
127  lorder(i) = i
128 end do
129 
130 call quick_sort(n,1,n,list,lorder)
131 
132 if (present(order)) order = lorder
133 
134 end subroutine qsort_qsort_real
135 # 71 "/Users/miesch/JEDI/code/working_copy/public/fv3-bundle/saber/src/saber/external/tools_qsort.fypp"
136 
137 # 73 "/Users/miesch/JEDI/code/working_copy/public/fv3-bundle/saber/src/saber/external/tools_qsort.fypp"
138 !----------------------------------------------------------------------
139 ! Subroutine: qsort_quick_sort_int
140 !> Sort an integer subvector
141 !----------------------------------------------------------------------
142 recursive subroutine qsort_quick_sort_int(n,left_end,right_end,list,order)
143 
144 implicit none
145 
146 ! Passed variables
147 integer,intent(in) :: n !< Input vector size
148 integer,intent(in) :: left_end !< Left end of the vector
149 integer,intent(in) :: right_end !< Right end of the vector
150 integer(kind_int),intent(inout) :: list(n) !< Vector to sort
151 integer,intent(inout) :: order(n) !< Positions of the elements in the original order
152 
153 ! Local variables
154 integer,parameter :: max_simple_sort_size = 6
155 integer :: i,j,itemp
156 integer(kind_int) :: reference,temp
157 
158 if (right_end<left_end+max_simple_sort_size) then
159  ! Use interchange sort for small lists
160  call interchange_sort(n,left_end,right_end,list,order)
161 else
162  ! Use partition ("quick") sort
163  reference = list((left_end+right_end)/2)
164  i = left_end-1
165  j = right_end+1
166  do
167  ! Scan list from left end until element >= reference is found
168  do
169  i = i+1
170  if (.not.inf(list(i),reference)) exit
171  end do
172  ! Scan list from right end until element <= reference is found
173  do
174  j = j-1
175  if (.not.sup(list(j),reference)) exit
176  end do
177 
178  if (i<j) then
179  ! Swap two out-of-order elements
180  temp = list(i)
181  list(i) = list(j)
182  list(j) = temp
183  itemp = order(i)
184  order(i) = order(j)
185  order(j) = itemp
186  elseif (i==j) then
187  i = i+1
188  exit
189  else
190  exit
191  end if
192  end do
193 
194  if (left_end<j) call quick_sort(n,left_end,j,list,order)
195  if (i<right_end) call quick_sort(n,i,right_end,list,order)
196 end if
197 
198 end subroutine qsort_quick_sort_int
199 # 73 "/Users/miesch/JEDI/code/working_copy/public/fv3-bundle/saber/src/saber/external/tools_qsort.fypp"
200 !----------------------------------------------------------------------
201 ! Subroutine: qsort_quick_sort_real
202 !> Sort an integer subvector
203 !----------------------------------------------------------------------
204 recursive subroutine qsort_quick_sort_real(n,left_end,right_end,list,order)
205 
206 implicit none
207 
208 ! Passed variables
209 integer,intent(in) :: n !< Input vector size
210 integer,intent(in) :: left_end !< Left end of the vector
211 integer,intent(in) :: right_end !< Right end of the vector
212 real(kind_real),intent(inout) :: list(n) !< Vector to sort
213 integer,intent(inout) :: order(n) !< Positions of the elements in the original order
214 
215 ! Local variables
216 integer,parameter :: max_simple_sort_size = 6
217 integer :: i,j,itemp
218 real(kind_real) :: reference,temp
219 
220 if (right_end<left_end+max_simple_sort_size) then
221  ! Use interchange sort for small lists
222  call interchange_sort(n,left_end,right_end,list,order)
223 else
224  ! Use partition ("quick") sort
225  reference = list((left_end+right_end)/2)
226  i = left_end-1
227  j = right_end+1
228  do
229  ! Scan list from left end until element >= reference is found
230  do
231  i = i+1
232  if (.not.inf(list(i),reference)) exit
233  end do
234  ! Scan list from right end until element <= reference is found
235  do
236  j = j-1
237  if (.not.sup(list(j),reference)) exit
238  end do
239 
240  if (i<j) then
241  ! Swap two out-of-order elements
242  temp = list(i)
243  list(i) = list(j)
244  list(j) = temp
245  itemp = order(i)
246  order(i) = order(j)
247  order(j) = itemp
248  elseif (i==j) then
249  i = i+1
250  exit
251  else
252  exit
253  end if
254  end do
255 
256  if (left_end<j) call quick_sort(n,left_end,j,list,order)
257  if (i<right_end) call quick_sort(n,i,right_end,list,order)
258 end if
259 
260 end subroutine qsort_quick_sort_real
261 # 135 "/Users/miesch/JEDI/code/working_copy/public/fv3-bundle/saber/src/saber/external/tools_qsort.fypp"
262 
263 # 137 "/Users/miesch/JEDI/code/working_copy/public/fv3-bundle/saber/src/saber/external/tools_qsort.fypp"
264 !----------------------------------------------------------------------
265 ! Subroutine: qsort_interchange_sort_int
266 !> Interchange integers
267 !----------------------------------------------------------------------
268 subroutine qsort_interchange_sort_int(n,left_end,right_end,list,order)
269 
270 implicit none
271 
272 ! Passed variables
273 integer,intent(in) :: n !< Input vector size
274 integer,intent(in) :: left_end !< Left end of the vector
275 integer,intent(in) :: right_end !< Right end of the vector
276 integer(kind_int),intent(inout) :: list(n) !< Vector to sort
277 integer,intent(inout) :: order(n) !< Positions of the elements in the original order
278 
279 ! Local variables
280 integer :: i,j,itemp
281 integer(kind_int) :: temp
282 
283 ! Set name
284 
285 
286 ! Probe in
287 
288 
289 do i=left_end,right_end-1
290  do j=i+1,right_end
291  if (sup(list(i),list(j))) then
292  temp = list(i)
293  list(i) = list(j)
294  list(j) = temp
295  itemp = order(i)
296  order(i) = order(j)
297  order(j) = itemp
298  end if
299  end do
300 end do
301 
302 ! Probe out
303 
304 
305 end subroutine qsort_interchange_sort_int
306 # 137 "/Users/miesch/JEDI/code/working_copy/public/fv3-bundle/saber/src/saber/external/tools_qsort.fypp"
307 !----------------------------------------------------------------------
308 ! Subroutine: qsort_interchange_sort_real
309 !> Interchange integers
310 !----------------------------------------------------------------------
311 subroutine qsort_interchange_sort_real(n,left_end,right_end,list,order)
312 
313 implicit none
314 
315 ! Passed variables
316 integer,intent(in) :: n !< Input vector size
317 integer,intent(in) :: left_end !< Left end of the vector
318 integer,intent(in) :: right_end !< Right end of the vector
319 real(kind_real),intent(inout) :: list(n) !< Vector to sort
320 integer,intent(inout) :: order(n) !< Positions of the elements in the original order
321 
322 ! Local variables
323 integer :: i,j,itemp
324 real(kind_real) :: temp
325 
326 ! Set name
327 
328 
329 ! Probe in
330 
331 
332 do i=left_end,right_end-1
333  do j=i+1,right_end
334  if (sup(list(i),list(j))) then
335  temp = list(i)
336  list(i) = list(j)
337  list(j) = temp
338  itemp = order(i)
339  order(i) = order(j)
340  order(j) = itemp
341  end if
342  end do
343 end do
344 
345 ! Probe out
346 
347 
348 end subroutine qsort_interchange_sort_real
349 # 180 "/Users/miesch/JEDI/code/working_copy/public/fv3-bundle/saber/src/saber/external/tools_qsort.fypp"
350 
351 end module tools_qsort
Kinds definition.
Definition: tools_kinds.F90:9
integer, parameter, public kind_int
Integer kind.
Definition: tools_kinds.F90:17
integer, parameter, public kind_real
Real kind alias for the whole code.
Definition: tools_kinds.F90:25
Generic ranks, dimensions and types.
Definition: tools_qsort.F90:46
recursive subroutine qsort_quick_sort_real(n, left_end, right_end, list, order)
Sort an integer subvector.
recursive subroutine qsort_qsort_int(n, list, order)
Sort a subvector.
Definition: tools_qsort.F90:87
recursive subroutine qsort_quick_sort_int(n, left_end, right_end, list, order)
Sort an integer subvector.
subroutine qsort_interchange_sort_int(n, left_end, right_end, list, order)
Interchange integers.
recursive subroutine qsort_qsort_real(n, list, order)
Sort a subvector.
subroutine qsort_interchange_sort_real(n, left_end, right_end, list, order)
Interchange integers.
Generic ranks, dimensions and types.
Definition: tools_repro.F90:42