root / src / m_mrgrnk.f90 @ 2
Historique | Voir | Annoter | Télécharger (17,68 ko)
1 |
!!! Downloaded from http://www.fortran-2000.com/rank/index.html |
---|---|
2 |
!!! on October 13th, 2010 |
3 |
|
4 |
Module m_mrgrnk |
5 |
! PFL 2010 Oct 13 -> |
6 |
!Integer, Parameter :: kdp = selected_real_kind(15) |
7 |
Integer, Parameter :: kdp = KIND(1.0D0) |
8 |
! <- PFL 2010 Oct 13 |
9 |
public :: mrgrnk |
10 |
private :: kdp |
11 |
private :: R_mrgrnk, I_mrgrnk, D_mrgrnk |
12 |
interface mrgrnk |
13 |
module procedure D_mrgrnk, R_mrgrnk, I_mrgrnk |
14 |
end interface mrgrnk |
15 |
contains |
16 |
|
17 |
Subroutine D_mrgrnk (XDONT, IRNGT) |
18 |
! Subroutine Dmrgrnk (XDONT, IRNGT) |
19 |
! __________________________________________________________ |
20 |
! MRGRNK = Merge-sort ranking of an array |
21 |
! For performance reasons, the first 2 passes are taken |
22 |
! out of the standard loop, and use dedicated coding. |
23 |
! __________________________________________________________ |
24 |
! __________________________________________________________ |
25 |
|
26 |
use VarTypes |
27 |
|
28 |
IMPLICIT NONE |
29 |
|
30 |
|
31 |
interface |
32 |
function valid(string) result (isValid) |
33 |
logical :: isValid |
34 |
character(*), intent(in) :: string |
35 |
end function valid |
36 |
end interface |
37 |
|
38 |
|
39 |
|
40 |
Real (KREAL), Dimension (:), Intent (In) :: XDONT |
41 |
Integer(KINT), Dimension (:), Intent (Out) :: IRNGT |
42 |
! __________________________________________________________ |
43 |
Real (KREAL) :: XVALA, XVALB |
44 |
! |
45 |
Integer(KINT), ALLOCATABLE :: JWRKT(:) ! SIZE(IRNGT) |
46 |
Integer(KINT) :: LMTNA, LMTNC, IRNG1, IRNG2 |
47 |
Integer(KINT) :: NVAL, IIND, IWRKD, IWRK, IWRKF, JINDA, IINDA, IINDB |
48 |
|
49 |
LOGICAL :: Debug |
50 |
|
51 |
Debug=Valid("DEBUG MRGRNK") |
52 |
|
53 |
if (debug) WRITE(*,*) "================================= Entering DMRGRNK ===============" |
54 |
! |
55 |
NVAL = Min (SIZE(XDONT), SIZE(IRNGT)) |
56 |
if (debug) WRITE(*,*) "D_mrgrnk",NVAL, Size(XDONT),SIZE(IRNGT) |
57 |
Select Case (NVAL) |
58 |
Case (:0) |
59 |
Return |
60 |
Case (1) |
61 |
IRNGT (1) = 1 |
62 |
Return |
63 |
Case Default |
64 |
Continue |
65 |
End Select |
66 |
|
67 |
if (debug) WRITE(*,*) "D_mrgrnk, XDONT",XDONT |
68 |
if (debug) WRITE(*,*) "D_mrgrnk, IRNGT",IRNGT |
69 |
|
70 |
ALLOCATE(JWRKT(SIZE(IRNGT))) |
71 |
! |
72 |
! Fill-in the index array, creating ordered couples |
73 |
! |
74 |
Do IIND = 2, NVAL, 2 |
75 |
If (XDONT(IIND-1) <= XDONT(IIND)) Then |
76 |
IRNGT (IIND-1) = IIND - 1 |
77 |
IRNGT (IIND) = IIND |
78 |
Else |
79 |
IRNGT (IIND-1) = IIND |
80 |
IRNGT (IIND) = IIND - 1 |
81 |
End If |
82 |
End Do |
83 |
If (Modulo(NVAL, 2) /= 0) Then |
84 |
IRNGT (NVAL) = NVAL |
85 |
End If |
86 |
! |
87 |
! We will now have ordered subsets A - B - A - B - ... |
88 |
! and merge A and B couples into C - C - ... |
89 |
! |
90 |
LMTNA = 2 |
91 |
LMTNC = 4 |
92 |
! |
93 |
! First iteration. The length of the ordered subsets goes from 2 to 4 |
94 |
! |
95 |
Do |
96 |
If (NVAL <= 2) Exit |
97 |
! |
98 |
! Loop on merges of A and B into C |
99 |
! |
100 |
Do IWRKD = 0, NVAL - 1, 4 |
101 |
If ((IWRKD+4) > NVAL) Then |
102 |
If ((IWRKD+2) >= NVAL) Exit |
103 |
! |
104 |
! 1 2 3 |
105 |
! |
106 |
If (XDONT(IRNGT(IWRKD+2)) <= XDONT(IRNGT(IWRKD+3))) Exit |
107 |
! |
108 |
! 1 3 2 |
109 |
! |
110 |
If (XDONT(IRNGT(IWRKD+1)) <= XDONT(IRNGT(IWRKD+3))) Then |
111 |
IRNG2 = IRNGT (IWRKD+2) |
112 |
IRNGT (IWRKD+2) = IRNGT (IWRKD+3) |
113 |
IRNGT (IWRKD+3) = IRNG2 |
114 |
! |
115 |
! 3 1 2 |
116 |
! |
117 |
Else |
118 |
IRNG1 = IRNGT (IWRKD+1) |
119 |
IRNGT (IWRKD+1) = IRNGT (IWRKD+3) |
120 |
IRNGT (IWRKD+3) = IRNGT (IWRKD+2) |
121 |
IRNGT (IWRKD+2) = IRNG1 |
122 |
End If |
123 |
Exit |
124 |
End If |
125 |
! |
126 |
! 1 2 3 4 |
127 |
! |
128 |
If (XDONT(IRNGT(IWRKD+2)) <= XDONT(IRNGT(IWRKD+3))) Cycle |
129 |
! |
130 |
! 1 3 x x |
131 |
! |
132 |
If (XDONT(IRNGT(IWRKD+1)) <= XDONT(IRNGT(IWRKD+3))) Then |
133 |
IRNG2 = IRNGT (IWRKD+2) |
134 |
IRNGT (IWRKD+2) = IRNGT (IWRKD+3) |
135 |
If (XDONT(IRNG2) <= XDONT(IRNGT(IWRKD+4))) Then |
136 |
! 1 3 2 4 |
137 |
IRNGT (IWRKD+3) = IRNG2 |
138 |
Else |
139 |
! 1 3 4 2 |
140 |
IRNGT (IWRKD+3) = IRNGT (IWRKD+4) |
141 |
IRNGT (IWRKD+4) = IRNG2 |
142 |
End If |
143 |
! |
144 |
! 3 x x x |
145 |
! |
146 |
Else |
147 |
IRNG1 = IRNGT (IWRKD+1) |
148 |
IRNG2 = IRNGT (IWRKD+2) |
149 |
IRNGT (IWRKD+1) = IRNGT (IWRKD+3) |
150 |
If (XDONT(IRNG1) <= XDONT(IRNGT(IWRKD+4))) Then |
151 |
IRNGT (IWRKD+2) = IRNG1 |
152 |
If (XDONT(IRNG2) <= XDONT(IRNGT(IWRKD+4))) Then |
153 |
! 3 1 2 4 |
154 |
IRNGT (IWRKD+3) = IRNG2 |
155 |
Else |
156 |
! 3 1 4 2 |
157 |
IRNGT (IWRKD+3) = IRNGT (IWRKD+4) |
158 |
IRNGT (IWRKD+4) = IRNG2 |
159 |
End If |
160 |
Else |
161 |
! 3 4 1 2 |
162 |
IRNGT (IWRKD+2) = IRNGT (IWRKD+4) |
163 |
IRNGT (IWRKD+3) = IRNG1 |
164 |
IRNGT (IWRKD+4) = IRNG2 |
165 |
End If |
166 |
End If |
167 |
End Do |
168 |
! |
169 |
! The Cs become As and Bs |
170 |
! |
171 |
LMTNA = 4 |
172 |
Exit |
173 |
End Do |
174 |
! |
175 |
! Iteration loop. Each time, the length of the ordered subsets |
176 |
! is doubled. |
177 |
! |
178 |
Do |
179 |
If (LMTNA >= NVAL) Exit |
180 |
IWRKF = 0 |
181 |
LMTNC = 2 * LMTNC |
182 |
! |
183 |
! Loop on merges of A and B into C |
184 |
! |
185 |
Do |
186 |
IWRK = IWRKF |
187 |
IWRKD = IWRKF + 1 |
188 |
JINDA = IWRKF + LMTNA |
189 |
IWRKF = IWRKF + LMTNC |
190 |
If (IWRKF >= NVAL) Then |
191 |
If (JINDA >= NVAL) Exit |
192 |
IWRKF = NVAL |
193 |
End If |
194 |
IINDA = 1 |
195 |
IINDB = JINDA + 1 |
196 |
! |
197 |
! Shortcut for the case when the max of A is smaller |
198 |
! than the min of B. This line may be activated when the |
199 |
! initial set is already close to sorted. |
200 |
! |
201 |
! IF (XDONT(IRNGT(JINDA)) <= XDONT(IRNGT(IINDB))) CYCLE |
202 |
! |
203 |
! One steps in the C subset, that we build in the final rank array |
204 |
! |
205 |
! Make a copy of the rank array for the merge iteration |
206 |
! |
207 |
JWRKT (1:LMTNA) = IRNGT (IWRKD:JINDA) |
208 |
! |
209 |
XVALA = XDONT (JWRKT(IINDA)) |
210 |
XVALB = XDONT (IRNGT(IINDB)) |
211 |
! |
212 |
Do |
213 |
IWRK = IWRK + 1 |
214 |
! |
215 |
! We still have unprocessed values in both A and B |
216 |
! |
217 |
If (XVALA > XVALB) Then |
218 |
IRNGT (IWRK) = IRNGT (IINDB) |
219 |
IINDB = IINDB + 1 |
220 |
If (IINDB > IWRKF) Then |
221 |
! Only A still with unprocessed values |
222 |
IRNGT (IWRK+1:IWRKF) = JWRKT (IINDA:LMTNA) |
223 |
Exit |
224 |
End If |
225 |
XVALB = XDONT (IRNGT(IINDB)) |
226 |
Else |
227 |
IRNGT (IWRK) = JWRKT (IINDA) |
228 |
IINDA = IINDA + 1 |
229 |
If (IINDA > LMTNA) Exit! Only B still with unprocessed values |
230 |
XVALA = XDONT (JWRKT(IINDA)) |
231 |
End If |
232 |
! |
233 |
End Do |
234 |
End Do |
235 |
! |
236 |
! The Cs become As and Bs |
237 |
! |
238 |
LMTNA = 2 * LMTNA |
239 |
End Do |
240 |
|
241 |
DEALLOCATE(JWRKT) |
242 |
if (debug) WRITE(*,*) "================================= Exiting DMRGRNK ===============" |
243 |
! |
244 |
Return |
245 |
! |
246 |
End Subroutine D_mrgrnk |
247 |
|
248 |
Subroutine R_mrgrnk (XDONT, IRNGT) |
249 |
! __________________________________________________________ |
250 |
! MRGRNK = Merge-sort ranking of an array |
251 |
! For performance reasons, the first 2 passes are taken |
252 |
! out of the standard loop, and use dedicated coding. |
253 |
! __________________________________________________________ |
254 |
! _________________________________________________________ |
255 |
Real, Dimension (:), Intent (In) :: XDONT |
256 |
Integer, Dimension (:), Intent (Out) :: IRNGT |
257 |
! __________________________________________________________ |
258 |
Real :: XVALA, XVALB |
259 |
! |
260 |
Integer, Dimension (SIZE(IRNGT)) :: JWRKT |
261 |
Integer :: LMTNA, LMTNC, IRNG1, IRNG2 |
262 |
Integer :: NVAL, IIND, IWRKD, IWRK, IWRKF, JINDA, IINDA, IINDB |
263 |
! |
264 |
|
265 |
NVAL = Min (SIZE(XDONT), SIZE(IRNGT)) |
266 |
! if (debug) WRITE(*,*) "R_MRGRNK:", NVAL |
267 |
Select Case (NVAL) |
268 |
Case (:0) |
269 |
Return |
270 |
Case (1) |
271 |
IRNGT (1) = 1 |
272 |
Return |
273 |
Case Default |
274 |
Continue |
275 |
End Select |
276 |
! |
277 |
! Fill-in the index array, creating ordered couples |
278 |
! |
279 |
Do IIND = 2, NVAL, 2 |
280 |
If (XDONT(IIND-1) <= XDONT(IIND)) Then |
281 |
IRNGT (IIND-1) = IIND - 1 |
282 |
IRNGT (IIND) = IIND |
283 |
Else |
284 |
IRNGT (IIND-1) = IIND |
285 |
IRNGT (IIND) = IIND - 1 |
286 |
End If |
287 |
End Do |
288 |
If (Modulo(NVAL, 2) /= 0) Then |
289 |
IRNGT (NVAL) = NVAL |
290 |
End If |
291 |
! |
292 |
! We will now have ordered subsets A - B - A - B - ... |
293 |
! and merge A and B couples into C - C - ... |
294 |
! |
295 |
LMTNA = 2 |
296 |
LMTNC = 4 |
297 |
! |
298 |
! First iteration. The length of the ordered subsets goes from 2 to 4 |
299 |
! |
300 |
Do |
301 |
If (NVAL <= 2) Exit |
302 |
! |
303 |
! Loop on merges of A and B into C |
304 |
! |
305 |
Do IWRKD = 0, NVAL - 1, 4 |
306 |
If ((IWRKD+4) > NVAL) Then |
307 |
If ((IWRKD+2) >= NVAL) Exit |
308 |
! |
309 |
! 1 2 3 |
310 |
! |
311 |
If (XDONT(IRNGT(IWRKD+2)) <= XDONT(IRNGT(IWRKD+3))) Exit |
312 |
! |
313 |
! 1 3 2 |
314 |
! |
315 |
If (XDONT(IRNGT(IWRKD+1)) <= XDONT(IRNGT(IWRKD+3))) Then |
316 |
IRNG2 = IRNGT (IWRKD+2) |
317 |
IRNGT (IWRKD+2) = IRNGT (IWRKD+3) |
318 |
IRNGT (IWRKD+3) = IRNG2 |
319 |
! |
320 |
! 3 1 2 |
321 |
! |
322 |
Else |
323 |
IRNG1 = IRNGT (IWRKD+1) |
324 |
IRNGT (IWRKD+1) = IRNGT (IWRKD+3) |
325 |
IRNGT (IWRKD+3) = IRNGT (IWRKD+2) |
326 |
IRNGT (IWRKD+2) = IRNG1 |
327 |
End If |
328 |
Exit |
329 |
End If |
330 |
! |
331 |
! 1 2 3 4 |
332 |
! |
333 |
If (XDONT(IRNGT(IWRKD+2)) <= XDONT(IRNGT(IWRKD+3))) Cycle |
334 |
! |
335 |
! 1 3 x x |
336 |
! |
337 |
If (XDONT(IRNGT(IWRKD+1)) <= XDONT(IRNGT(IWRKD+3))) Then |
338 |
IRNG2 = IRNGT (IWRKD+2) |
339 |
IRNGT (IWRKD+2) = IRNGT (IWRKD+3) |
340 |
If (XDONT(IRNG2) <= XDONT(IRNGT(IWRKD+4))) Then |
341 |
! 1 3 2 4 |
342 |
IRNGT (IWRKD+3) = IRNG2 |
343 |
Else |
344 |
! 1 3 4 2 |
345 |
IRNGT (IWRKD+3) = IRNGT (IWRKD+4) |
346 |
IRNGT (IWRKD+4) = IRNG2 |
347 |
End If |
348 |
! |
349 |
! 3 x x x |
350 |
! |
351 |
Else |
352 |
IRNG1 = IRNGT (IWRKD+1) |
353 |
IRNG2 = IRNGT (IWRKD+2) |
354 |
IRNGT (IWRKD+1) = IRNGT (IWRKD+3) |
355 |
If (XDONT(IRNG1) <= XDONT(IRNGT(IWRKD+4))) Then |
356 |
IRNGT (IWRKD+2) = IRNG1 |
357 |
If (XDONT(IRNG2) <= XDONT(IRNGT(IWRKD+4))) Then |
358 |
! 3 1 2 4 |
359 |
IRNGT (IWRKD+3) = IRNG2 |
360 |
Else |
361 |
! 3 1 4 2 |
362 |
IRNGT (IWRKD+3) = IRNGT (IWRKD+4) |
363 |
IRNGT (IWRKD+4) = IRNG2 |
364 |
End If |
365 |
Else |
366 |
! 3 4 1 2 |
367 |
IRNGT (IWRKD+2) = IRNGT (IWRKD+4) |
368 |
IRNGT (IWRKD+3) = IRNG1 |
369 |
IRNGT (IWRKD+4) = IRNG2 |
370 |
End If |
371 |
End If |
372 |
End Do |
373 |
! |
374 |
! The Cs become As and Bs |
375 |
! |
376 |
LMTNA = 4 |
377 |
Exit |
378 |
End Do |
379 |
! |
380 |
! Iteration loop. Each time, the length of the ordered subsets |
381 |
! is doubled. |
382 |
! |
383 |
Do |
384 |
If (LMTNA >= NVAL) Exit |
385 |
IWRKF = 0 |
386 |
LMTNC = 2 * LMTNC |
387 |
! |
388 |
! Loop on merges of A and B into C |
389 |
! |
390 |
Do |
391 |
IWRK = IWRKF |
392 |
IWRKD = IWRKF + 1 |
393 |
JINDA = IWRKF + LMTNA |
394 |
IWRKF = IWRKF + LMTNC |
395 |
If (IWRKF >= NVAL) Then |
396 |
If (JINDA >= NVAL) Exit |
397 |
IWRKF = NVAL |
398 |
End If |
399 |
IINDA = 1 |
400 |
IINDB = JINDA + 1 |
401 |
! |
402 |
! Shortcut for the case when the max of A is smaller |
403 |
! than the min of B. This line may be activated when the |
404 |
! initial set is already close to sorted. |
405 |
! |
406 |
! IF (XDONT(IRNGT(JINDA)) <= XDONT(IRNGT(IINDB))) CYCLE |
407 |
! |
408 |
! One steps in the C subset, that we build in the final rank array |
409 |
! |
410 |
! Make a copy of the rank array for the merge iteration |
411 |
! |
412 |
JWRKT (1:LMTNA) = IRNGT (IWRKD:JINDA) |
413 |
! |
414 |
XVALA = XDONT (JWRKT(IINDA)) |
415 |
XVALB = XDONT (IRNGT(IINDB)) |
416 |
! |
417 |
Do |
418 |
IWRK = IWRK + 1 |
419 |
! |
420 |
! We still have unprocessed values in both A and B |
421 |
! |
422 |
If (XVALA > XVALB) Then |
423 |
IRNGT (IWRK) = IRNGT (IINDB) |
424 |
IINDB = IINDB + 1 |
425 |
If (IINDB > IWRKF) Then |
426 |
! Only A still with unprocessed values |
427 |
IRNGT (IWRK+1:IWRKF) = JWRKT (IINDA:LMTNA) |
428 |
Exit |
429 |
End If |
430 |
XVALB = XDONT (IRNGT(IINDB)) |
431 |
Else |
432 |
IRNGT (IWRK) = JWRKT (IINDA) |
433 |
IINDA = IINDA + 1 |
434 |
If (IINDA > LMTNA) Exit! Only B still with unprocessed values |
435 |
XVALA = XDONT (JWRKT(IINDA)) |
436 |
End If |
437 |
! |
438 |
End Do |
439 |
End Do |
440 |
! |
441 |
! The Cs become As and Bs |
442 |
! |
443 |
LMTNA = 2 * LMTNA |
444 |
End Do |
445 |
! |
446 |
Return |
447 |
! |
448 |
End Subroutine R_mrgrnk |
449 |
Subroutine I_mrgrnk (XDONT, IRNGT) |
450 |
! __________________________________________________________ |
451 |
! MRGRNK = Merge-sort ranking of an array |
452 |
! For performance reasons, the first 2 passes are taken |
453 |
! out of the standard loop, and use dedicated coding. |
454 |
! __________________________________________________________ |
455 |
! __________________________________________________________ |
456 |
Integer, Dimension (:), Intent (In) :: XDONT |
457 |
Integer, Dimension (:), Intent (Out) :: IRNGT |
458 |
! __________________________________________________________ |
459 |
Integer :: XVALA, XVALB |
460 |
! |
461 |
Integer, Dimension (SIZE(IRNGT)) :: JWRKT |
462 |
Integer :: LMTNA, LMTNC, IRNG1, IRNG2 |
463 |
Integer :: NVAL, IIND, IWRKD, IWRK, IWRKF, JINDA, IINDA, IINDB |
464 |
! |
465 |
NVAL = Min (SIZE(XDONT), SIZE(IRNGT)) |
466 |
! WRITE(*,*) "I_mrgrnk",NVAL |
467 |
Select Case (NVAL) |
468 |
Case (:0) |
469 |
Return |
470 |
Case (1) |
471 |
IRNGT (1) = 1 |
472 |
Return |
473 |
Case Default |
474 |
Continue |
475 |
End Select |
476 |
! |
477 |
! Fill-in the index array, creating ordered couples |
478 |
! |
479 |
Do IIND = 2, NVAL, 2 |
480 |
If (XDONT(IIND-1) <= XDONT(IIND)) Then |
481 |
IRNGT (IIND-1) = IIND - 1 |
482 |
IRNGT (IIND) = IIND |
483 |
Else |
484 |
IRNGT (IIND-1) = IIND |
485 |
IRNGT (IIND) = IIND - 1 |
486 |
End If |
487 |
End Do |
488 |
If (Modulo(NVAL, 2) /= 0) Then |
489 |
IRNGT (NVAL) = NVAL |
490 |
End If |
491 |
! |
492 |
! We will now have ordered subsets A - B - A - B - ... |
493 |
! and merge A and B couples into C - C - ... |
494 |
! |
495 |
LMTNA = 2 |
496 |
LMTNC = 4 |
497 |
! |
498 |
! First iteration. The length of the ordered subsets goes from 2 to 4 |
499 |
! |
500 |
Do |
501 |
If (NVAL <= 2) Exit |
502 |
! |
503 |
! Loop on merges of A and B into C |
504 |
! |
505 |
Do IWRKD = 0, NVAL - 1, 4 |
506 |
If ((IWRKD+4) > NVAL) Then |
507 |
If ((IWRKD+2) >= NVAL) Exit |
508 |
! |
509 |
! 1 2 3 |
510 |
! |
511 |
If (XDONT(IRNGT(IWRKD+2)) <= XDONT(IRNGT(IWRKD+3))) Exit |
512 |
! |
513 |
! 1 3 2 |
514 |
! |
515 |
If (XDONT(IRNGT(IWRKD+1)) <= XDONT(IRNGT(IWRKD+3))) Then |
516 |
IRNG2 = IRNGT (IWRKD+2) |
517 |
IRNGT (IWRKD+2) = IRNGT (IWRKD+3) |
518 |
IRNGT (IWRKD+3) = IRNG2 |
519 |
! |
520 |
! 3 1 2 |
521 |
! |
522 |
Else |
523 |
IRNG1 = IRNGT (IWRKD+1) |
524 |
IRNGT (IWRKD+1) = IRNGT (IWRKD+3) |
525 |
IRNGT (IWRKD+3) = IRNGT (IWRKD+2) |
526 |
IRNGT (IWRKD+2) = IRNG1 |
527 |
End If |
528 |
Exit |
529 |
End If |
530 |
! |
531 |
! 1 2 3 4 |
532 |
! |
533 |
If (XDONT(IRNGT(IWRKD+2)) <= XDONT(IRNGT(IWRKD+3))) Cycle |
534 |
! |
535 |
! 1 3 x x |
536 |
! |
537 |
If (XDONT(IRNGT(IWRKD+1)) <= XDONT(IRNGT(IWRKD+3))) Then |
538 |
IRNG2 = IRNGT (IWRKD+2) |
539 |
IRNGT (IWRKD+2) = IRNGT (IWRKD+3) |
540 |
If (XDONT(IRNG2) <= XDONT(IRNGT(IWRKD+4))) Then |
541 |
! 1 3 2 4 |
542 |
IRNGT (IWRKD+3) = IRNG2 |
543 |
Else |
544 |
! 1 3 4 2 |
545 |
IRNGT (IWRKD+3) = IRNGT (IWRKD+4) |
546 |
IRNGT (IWRKD+4) = IRNG2 |
547 |
End If |
548 |
! |
549 |
! 3 x x x |
550 |
! |
551 |
Else |
552 |
IRNG1 = IRNGT (IWRKD+1) |
553 |
IRNG2 = IRNGT (IWRKD+2) |
554 |
IRNGT (IWRKD+1) = IRNGT (IWRKD+3) |
555 |
If (XDONT(IRNG1) <= XDONT(IRNGT(IWRKD+4))) Then |
556 |
IRNGT (IWRKD+2) = IRNG1 |
557 |
If (XDONT(IRNG2) <= XDONT(IRNGT(IWRKD+4))) Then |
558 |
! 3 1 2 4 |
559 |
IRNGT (IWRKD+3) = IRNG2 |
560 |
Else |
561 |
! 3 1 4 2 |
562 |
IRNGT (IWRKD+3) = IRNGT (IWRKD+4) |
563 |
IRNGT (IWRKD+4) = IRNG2 |
564 |
End If |
565 |
Else |
566 |
! 3 4 1 2 |
567 |
IRNGT (IWRKD+2) = IRNGT (IWRKD+4) |
568 |
IRNGT (IWRKD+3) = IRNG1 |
569 |
IRNGT (IWRKD+4) = IRNG2 |
570 |
End If |
571 |
End If |
572 |
End Do |
573 |
! |
574 |
! The Cs become As and Bs |
575 |
! |
576 |
LMTNA = 4 |
577 |
Exit |
578 |
End Do |
579 |
! |
580 |
! Iteration loop. Each time, the length of the ordered subsets |
581 |
! is doubled. |
582 |
! |
583 |
Do |
584 |
If (LMTNA >= NVAL) Exit |
585 |
IWRKF = 0 |
586 |
LMTNC = 2 * LMTNC |
587 |
! |
588 |
! Loop on merges of A and B into C |
589 |
! |
590 |
Do |
591 |
IWRK = IWRKF |
592 |
IWRKD = IWRKF + 1 |
593 |
JINDA = IWRKF + LMTNA |
594 |
IWRKF = IWRKF + LMTNC |
595 |
If (IWRKF >= NVAL) Then |
596 |
If (JINDA >= NVAL) Exit |
597 |
IWRKF = NVAL |
598 |
End If |
599 |
IINDA = 1 |
600 |
IINDB = JINDA + 1 |
601 |
! |
602 |
! Shortcut for the case when the max of A is smaller |
603 |
! than the min of B. This line may be activated when the |
604 |
! initial set is already close to sorted. |
605 |
! |
606 |
! IF (XDONT(IRNGT(JINDA)) <= XDONT(IRNGT(IINDB))) CYCLE |
607 |
! |
608 |
! One steps in the C subset, that we build in the final rank array |
609 |
! |
610 |
! Make a copy of the rank array for the merge iteration |
611 |
! |
612 |
JWRKT (1:LMTNA) = IRNGT (IWRKD:JINDA) |
613 |
! |
614 |
XVALA = XDONT (JWRKT(IINDA)) |
615 |
XVALB = XDONT (IRNGT(IINDB)) |
616 |
! |
617 |
Do |
618 |
IWRK = IWRK + 1 |
619 |
! |
620 |
! We still have unprocessed values in both A and B |
621 |
! |
622 |
If (XVALA > XVALB) Then |
623 |
IRNGT (IWRK) = IRNGT (IINDB) |
624 |
IINDB = IINDB + 1 |
625 |
If (IINDB > IWRKF) Then |
626 |
! Only A still with unprocessed values |
627 |
IRNGT (IWRK+1:IWRKF) = JWRKT (IINDA:LMTNA) |
628 |
Exit |
629 |
End If |
630 |
XVALB = XDONT (IRNGT(IINDB)) |
631 |
Else |
632 |
IRNGT (IWRK) = JWRKT (IINDA) |
633 |
IINDA = IINDA + 1 |
634 |
If (IINDA > LMTNA) Exit! Only B still with unprocessed values |
635 |
XVALA = XDONT (JWRKT(IINDA)) |
636 |
End If |
637 |
! |
638 |
End Do |
639 |
End Do |
640 |
! |
641 |
! The Cs become As and Bs |
642 |
! |
643 |
LMTNA = 2 * LMTNA |
644 |
End Do |
645 |
! |
646 |
Return |
647 |
! |
648 |
End Subroutine I_mrgrnk |
649 |
end module m_mrgrnk |