Statistiques
| Révision :

root / src / m_mrgrnk.f90 @ 2

Historique | Voir | Annoter | Télécharger (17,68 ko)

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