root / src / m_mrgrnk.f90 @ 1
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 |