LMDZ
mrgrnk.F90
Go to the documentation of this file.
1 Module m_mrgrnk
2 Integer, Parameter :: kdp = selected_real_kind(15)
3 public :: mrgrnk
4 private :: kdp
5 private :: i_mrgrnk, d_mrgrnk
6 interface mrgrnk
7  module procedure d_mrgrnk, i_mrgrnk
8 end interface mrgrnk
9 contains
10 
11 Subroutine d_mrgrnk (XDONT, IRNGT)
12 ! __________________________________________________________
13 ! MRGRNK = Merge-sort ranking of an array
14 ! For performance reasons, the first 2 passes are taken
15 ! out of the standard loop, and use dedicated coding.
16 ! __________________________________________________________
17 ! __________________________________________________________
18  Real (kind=kdp), Dimension (:), Intent (In) :: XDONT
19  Integer, Dimension (:), Intent (Out) :: IRNGT
20 ! __________________________________________________________
21  Real (kind=kdp) :: XVALA, XVALB
22 !
23  Integer, Dimension (SIZE(IRNGT)) :: JWRKT
24  Integer :: LMTNA, LMTNC, IRNG1, IRNG2
25  Integer :: NVAL, IIND, IWRKD, IWRK, IWRKF, JINDA, IINDA, IINDB
26 !
27  nval = min(SIZE(xdont), SIZE(irngt))
28  Select Case (nval)
29  Case (:0)
30  Return
31  Case (1)
32  irngt(1) = 1
33  Return
34  Case Default
35  Continue
36  End Select
37 !
38 ! Fill-in the index array, creating ordered couples
39 !
40  Do iind = 2, nval, 2
41  If (xdont(iind-1) <= xdont(iind)) Then
42  irngt(iind-1) = iind - 1
43  irngt(iind) = iind
44  Else
45  irngt(iind-1) = iind
46  irngt(iind) = iind - 1
47  End If
48  End Do
49  If (modulo(nval, 2) /= 0) Then
50  irngt(nval) = nval
51  End If
52 !
53 ! We will now have ordered subsets A - B - A - B - ...
54 ! and merge A and B couples into C - C - ...
55 !
56  lmtna = 2
57  lmtnc = 4
58 !
59 ! First iteration. The length of the ordered subsets goes from 2 to 4
60 !
61  Do
62  If (nval <= 2) Exit
63 !
64 ! Loop on merges of A and B into C
65 !
66  Do iwrkd = 0, nval - 1, 4
67  If ((iwrkd+4) > nval) Then
68  If ((iwrkd+2) >= nval) Exit
69 !
70 ! 1 2 3
71 !
72  If (xdont(irngt(iwrkd+2)) <= xdont(irngt(iwrkd+3))) Exit
73 !
74 ! 1 3 2
75 !
76  If (xdont(irngt(iwrkd+1)) <= xdont(irngt(iwrkd+3))) Then
77  irng2 = irngt(iwrkd+2)
78  irngt(iwrkd+2) = irngt(iwrkd+3)
79  irngt(iwrkd+3) = irng2
80 !
81 ! 3 1 2
82 !
83  Else
84  irng1 = irngt(iwrkd+1)
85  irngt(iwrkd+1) = irngt(iwrkd+3)
86  irngt(iwrkd+3) = irngt(iwrkd+2)
87  irngt(iwrkd+2) = irng1
88  End If
89  Exit
90  End If
91 !
92 ! 1 2 3 4
93 !
94  If (xdont(irngt(iwrkd+2)) <= xdont(irngt(iwrkd+3))) cycle
95 !
96 ! 1 3 x x
97 !
98  If (xdont(irngt(iwrkd+1)) <= xdont(irngt(iwrkd+3))) Then
99  irng2 = irngt(iwrkd+2)
100  irngt(iwrkd+2) = irngt(iwrkd+3)
101  If (xdont(irng2) <= xdont(irngt(iwrkd+4))) Then
102 ! 1 3 2 4
103  irngt(iwrkd+3) = irng2
104  Else
105 ! 1 3 4 2
106  irngt(iwrkd+3) = irngt(iwrkd+4)
107  irngt(iwrkd+4) = irng2
108  End If
109 !
110 ! 3 x x x
111 !
112  Else
113  irng1 = irngt(iwrkd+1)
114  irng2 = irngt(iwrkd+2)
115  irngt(iwrkd+1) = irngt(iwrkd+3)
116  If (xdont(irng1) <= xdont(irngt(iwrkd+4))) Then
117  irngt(iwrkd+2) = irng1
118  If (xdont(irng2) <= xdont(irngt(iwrkd+4))) Then
119 ! 3 1 2 4
120  irngt(iwrkd+3) = irng2
121  Else
122 ! 3 1 4 2
123  irngt(iwrkd+3) = irngt(iwrkd+4)
124  irngt(iwrkd+4) = irng2
125  End If
126  Else
127 ! 3 4 1 2
128  irngt(iwrkd+2) = irngt(iwrkd+4)
129  irngt(iwrkd+3) = irng1
130  irngt(iwrkd+4) = irng2
131  End If
132  End If
133  End Do
134 !
135 ! The Cs become As and Bs
136 !
137  lmtna = 4
138  Exit
139  End Do
140 !
141 ! Iteration loop. Each time, the length of the ordered subsets
142 ! is doubled.
143 !
144  Do
145  If (lmtna >= nval) Exit
146  iwrkf = 0
147  lmtnc = 2 * lmtnc
148 !
149 ! Loop on merges of A and B into C
150 !
151  Do
152  iwrk = iwrkf
153  iwrkd = iwrkf + 1
154  jinda = iwrkf + lmtna
155  iwrkf = iwrkf + lmtnc
156  If (iwrkf >= nval) Then
157  If (jinda >= nval) Exit
158  iwrkf = nval
159  End If
160  iinda = 1
161  iindb = jinda + 1
162 !
163 ! Shortcut for the case when the max of A is smaller
164 ! than the min of B. This line may be activated when the
165 ! initial set is already close to sorted.
166 !
167 ! IF (XDONT(IRNGT(JINDA)) <= XDONT(IRNGT(IINDB))) CYCLE
168 !
169 ! One steps in the C subset, that we build in the final rank array
170 !
171 ! Make a copy of the rank array for the merge iteration
172 !
173  jwrkt(1:lmtna) = irngt(iwrkd:jinda)
174 !
175  xvala = xdont(jwrkt(iinda))
176  xvalb = xdont(irngt(iindb))
177 !
178  Do
179  iwrk = iwrk + 1
180 !
181 ! We still have unprocessed values in both A and B
182 !
183  If (xvala > xvalb) Then
184  irngt(iwrk) = irngt(iindb)
185  iindb = iindb + 1
186  If (iindb > iwrkf) Then
187 ! Only A still with unprocessed values
188  irngt(iwrk+1:iwrkf) = jwrkt(iinda:lmtna)
189  Exit
190  End If
191  xvalb = xdont(irngt(iindb))
192  Else
193  irngt(iwrk) = jwrkt(iinda)
194  iinda = iinda + 1
195  If (iinda > lmtna) exit! Only B still with unprocessed values
196  xvala = xdont(jwrkt(iinda))
197  End If
198 !
199  End Do
200  End Do
201 !
202 ! The Cs become As and Bs
203 !
204  lmtna = 2 * lmtna
205  End Do
206 !
207  Return
208 !
209 End Subroutine d_mrgrnk
210 
211 Subroutine i_mrgrnk (XDONT, IRNGT)
212 ! __________________________________________________________
213 ! MRGRNK = Merge-sort ranking of an array
214 ! For performance reasons, the first 2 passes are taken
215 ! out of the standard loop, and use dedicated coding.
216 ! __________________________________________________________
217 ! __________________________________________________________
218  Integer, Dimension (:), Intent (In) :: XDONT
219  Integer, Dimension (:), Intent (Out) :: IRNGT
220 ! __________________________________________________________
221  Integer :: XVALA, XVALB
222 !
223  Integer, Dimension (SIZE(IRNGT)) :: JWRKT
224  Integer :: LMTNA, LMTNC, IRNG1, IRNG2
225  Integer :: NVAL, IIND, IWRKD, IWRK, IWRKF, JINDA, IINDA, IINDB
226 !
227  nval = min(SIZE(xdont), SIZE(irngt))
228  Select Case (nval)
229  Case (:0)
230  Return
231  Case (1)
232  irngt(1) = 1
233  Return
234  Case Default
235  Continue
236  End Select
237 !
238 ! Fill-in the index array, creating ordered couples
239 !
240  Do iind = 2, nval, 2
241  If (xdont(iind-1) <= xdont(iind)) Then
242  irngt(iind-1) = iind - 1
243  irngt(iind) = iind
244  Else
245  irngt(iind-1) = iind
246  irngt(iind) = iind - 1
247  End If
248  End Do
249  If (modulo(nval, 2) /= 0) Then
250  irngt(nval) = nval
251  End If
252 !
253 ! We will now have ordered subsets A - B - A - B - ...
254 ! and merge A and B couples into C - C - ...
255 !
256  lmtna = 2
257  lmtnc = 4
258 !
259 ! First iteration. The length of the ordered subsets goes from 2 to 4
260 !
261  Do
262  If (nval <= 2) Exit
263 !
264 ! Loop on merges of A and B into C
265 !
266  Do iwrkd = 0, nval - 1, 4
267  If ((iwrkd+4) > nval) Then
268  If ((iwrkd+2) >= nval) Exit
269 !
270 ! 1 2 3
271 !
272  If (xdont(irngt(iwrkd+2)) <= xdont(irngt(iwrkd+3))) Exit
273 !
274 ! 1 3 2
275 !
276  If (xdont(irngt(iwrkd+1)) <= xdont(irngt(iwrkd+3))) Then
277  irng2 = irngt(iwrkd+2)
278  irngt(iwrkd+2) = irngt(iwrkd+3)
279  irngt(iwrkd+3) = irng2
280 !
281 ! 3 1 2
282 !
283  Else
284  irng1 = irngt(iwrkd+1)
285  irngt(iwrkd+1) = irngt(iwrkd+3)
286  irngt(iwrkd+3) = irngt(iwrkd+2)
287  irngt(iwrkd+2) = irng1
288  End If
289  Exit
290  End If
291 !
292 ! 1 2 3 4
293 !
294  If (xdont(irngt(iwrkd+2)) <= xdont(irngt(iwrkd+3))) cycle
295 !
296 ! 1 3 x x
297 !
298  If (xdont(irngt(iwrkd+1)) <= xdont(irngt(iwrkd+3))) Then
299  irng2 = irngt(iwrkd+2)
300  irngt(iwrkd+2) = irngt(iwrkd+3)
301  If (xdont(irng2) <= xdont(irngt(iwrkd+4))) Then
302 ! 1 3 2 4
303  irngt(iwrkd+3) = irng2
304  Else
305 ! 1 3 4 2
306  irngt(iwrkd+3) = irngt(iwrkd+4)
307  irngt(iwrkd+4) = irng2
308  End If
309 !
310 ! 3 x x x
311 !
312  Else
313  irng1 = irngt(iwrkd+1)
314  irng2 = irngt(iwrkd+2)
315  irngt(iwrkd+1) = irngt(iwrkd+3)
316  If (xdont(irng1) <= xdont(irngt(iwrkd+4))) Then
317  irngt(iwrkd+2) = irng1
318  If (xdont(irng2) <= xdont(irngt(iwrkd+4))) Then
319 ! 3 1 2 4
320  irngt(iwrkd+3) = irng2
321  Else
322 ! 3 1 4 2
323  irngt(iwrkd+3) = irngt(iwrkd+4)
324  irngt(iwrkd+4) = irng2
325  End If
326  Else
327 ! 3 4 1 2
328  irngt(iwrkd+2) = irngt(iwrkd+4)
329  irngt(iwrkd+3) = irng1
330  irngt(iwrkd+4) = irng2
331  End If
332  End If
333  End Do
334 !
335 ! The Cs become As and Bs
336 !
337  lmtna = 4
338  Exit
339  End Do
340 !
341 ! Iteration loop. Each time, the length of the ordered subsets
342 ! is doubled.
343 !
344  Do
345  If (lmtna >= nval) Exit
346  iwrkf = 0
347  lmtnc = 2 * lmtnc
348 !
349 ! Loop on merges of A and B into C
350 !
351  Do
352  iwrk = iwrkf
353  iwrkd = iwrkf + 1
354  jinda = iwrkf + lmtna
355  iwrkf = iwrkf + lmtnc
356  If (iwrkf >= nval) Then
357  If (jinda >= nval) Exit
358  iwrkf = nval
359  End If
360  iinda = 1
361  iindb = jinda + 1
362 !
363 ! Shortcut for the case when the max of A is smaller
364 ! than the min of B. This line may be activated when the
365 ! initial set is already close to sorted.
366 !
367 ! IF (XDONT(IRNGT(JINDA)) <= XDONT(IRNGT(IINDB))) CYCLE
368 !
369 ! One steps in the C subset, that we build in the final rank array
370 !
371 ! Make a copy of the rank array for the merge iteration
372 !
373  jwrkt(1:lmtna) = irngt(iwrkd:jinda)
374 !
375  xvala = xdont(jwrkt(iinda))
376  xvalb = xdont(irngt(iindb))
377 !
378  Do
379  iwrk = iwrk + 1
380 !
381 ! We still have unprocessed values in both A and B
382 !
383  If (xvala > xvalb) Then
384  irngt(iwrk) = irngt(iindb)
385  iindb = iindb + 1
386  If (iindb > iwrkf) Then
387 ! Only A still with unprocessed values
388  irngt(iwrk+1:iwrkf) = jwrkt(iinda:lmtna)
389  Exit
390  End If
391  xvalb = xdont(irngt(iindb))
392  Else
393  irngt(iwrk) = jwrkt(iinda)
394  iinda = iinda + 1
395  If (iinda > lmtna) exit! Only B still with unprocessed values
396  xvala = xdont(jwrkt(iinda))
397  End If
398 !
399  End Do
400  End Do
401 !
402 ! The Cs become As and Bs
403 !
404  lmtna = 2 * lmtna
405  End Do
406 !
407  Return
408 !
409 End Subroutine i_mrgrnk
410 end module m_mrgrnk
integer, parameter, private kdp
Definition: mrgrnk.F90:2
subroutine, private d_mrgrnk(XDONT, IRNGT)
Definition: mrgrnk.F90:12
subroutine, private i_mrgrnk(XDONT, IRNGT)
Definition: mrgrnk.F90:212