0.6.2-dev0
FORCES
FORtran lib for Comp. Env. Sys.
Loading...
Searching...
No Matches
mo_orderpack.f90
Go to the documentation of this file.
1!> \file mo_orderpack.f90
2!> \brief \copybrief mo_orderpack
3!> \details \copydetails mo_orderpack
4
5!> \brief Sort and ranking routines
6!> \details
7!! This module is the Orderpack 2.0 from Michel Olagnon.
8!! It provides order and unconditional, unique, and partial
9!! ranking, sorting, and permutation.
10!!
11!! <b> Unconditional ranking </b>
12!!
13!! \code{.f90} subroutine MRGRNK (XVALT, IMULT) \endcode
14!!
15!! Ranks array XVALT into index array IRNGT, using merge-sort.
16!! For performance reasons, the first 2 passes are taken out of the
17!! standard loop, and use dedicated coding.
18!!
19!! \code{.f90} subroutine MRGREF (XVALT, IRNGT) \endcode
20!!
21!! Ranks array XVALT into index array
22!! IRNGT, using merge-sort. This version is not optimized for performance,
23!! and is thus not as difficult to read as the previous one.
24!!
25!! <b> Partial ranking </b>
26!!
27!! \code{.f90} subroutine RNKPAR (XVALT, IRNGT, NORD) \endcode
28!!
29!! Ranks partially XVALT by IRNGT,
30!! up to order NORD (refined for speed). This routine uses a pivoting
31!! strategy such as the one of finding the median based on the quicksort
32!! algorithm, but we skew the pivot choice to try to bring it to NORD as
33!! fast as possible. It uses 2 temporary arrays, one where it stores the
34!! indices of the values smaller than the pivot, and the other for the
35!! indices of values larger than the pivot that we might still need later
36!! on. It iterates until it can bring the number of values in ILOWT to
37!! exactly NORD, and then uses an insertion sort to rank this set, since
38!! it is supposedly small.
39!!
40!! \code{.f90} subroutine RAPKNR (XVALT, IRNGT, NORD) \endcode
41!!
42!! Same as RNKPAR, but in
43!! decreasing order (RAPKNR = RNKPAR spelt backwards).
44!!
45!! \code{.f90} subroutine REFPAR (XVALT, IRNGT, NORD) \endcode
46!!
47!! Ranks partially XVALT by IRNGT,
48!! up to order NORD This version is not optimized for performance, and is
49!! thus not as difficult to read as some other ones. It uses a pivoting
50!! strategy such as the one of finding the median based on the quicksort
51!! algorithm. It uses a temporary array, where it stores the partially
52!! ranked indices of the values. It iterates until it can bring the
53!! number of values lower than the pivot to exactly NORD, and then uses
54!! an insertion sort to rank this set, since it is supposedly small.
55!!
56!! \code{.f90} subroutine RINPAR (XVALT, IRNGT, NORD) \endcode
57!!
58!! Ranks partially XVALT by IRNGT,
59!! up to order NORD This version is not optimized for performance, and is
60!! thus not as difficult to read as some other ones. It uses insertion
61!! sort, limiting insertion to the first NORD values. It does not use any
62!! work array and is faster when NORD is very small (2-5), but worst case
63!! behavior (intially inverse sorted) can easily happen. In many cases,
64!! the refined quicksort method is faster.
65!!
66!! \code{.f90} integer function INDNTH (XVALT, NORD) \endcode
67!!
68!! Returns the index of the NORDth
69!! value of XVALT (in increasing order) This routine uses a pivoting
70!! strategy such as the one of finding the median based on the quicksort
71!! algorithm, but we skew the pivot choice to try to bring it to NORD as
72!! fast as possible. It uses 2 temporary arrays, one where it stores the
73!! indices of the values smaller than the pivot, and the other for the
74!! indices of values larger than the pivot that we might still need later
75!! on. It iterates until it can bring the number of values in ILOWT to
76!! exactly NORD, and then takes out the original index of the maximum
77!! value in this set.
78!!
79!! \code{.f90} subroutine INDMED (XVALT, INDM) \endcode
80!!
81!! Returns the index of the median
82!! (((Size(XVALT)+1))/2th value) of XVALT This routine uses the recursive
83!! procedure described in Knuth, The Art of Computer Programming, vol. 3,
84!! 5.3.3 - This procedure is linear in time, and does not require to be
85!! able to interpolate in the set as the one used in INDNTH. It also has
86!! better worst case behavior than INDNTH, but is about 10% slower in
87!! average for random uniformly distributed values.
88!!
89!! Note that in Orderpack 1.0, this routine was a Function procedure, and
90!! is now changed to a Subroutine.
91!!
92!! <b> Unique ranking </b>
93!!
94!! \code{.f90} subroutine UNIRNK (XVALT, IRNGT, NUNI) \endcode
95!!
96!! Ranks an array, removing
97!! duplicate entries (uses merge sort). The routine is similar to pure
98!! merge-sort ranking, but on the last pass, it discards indices that
99!! correspond to duplicate entries. For performance reasons, the first 2
100!! passes are taken out of the standard loop, and use dedicated coding.
101!!
102!! \code{.f90} subroutine UNIPAR (XVALT, IRNGT, NORD) \endcode
103!!
104!! Ranks partially XVALT by IRNGT,
105!! up to order NORD at most, removing duplicate entries This routine uses
106!! a pivoting strategy such as the one of finding the median based on the
107!! quicksort algorithm, but we skew the pivot choice to try to bring it
108!! to NORD as quickly as possible. It uses 2 temporary arrays, one where
109!! it stores the indices of the values smaller than the pivot, and the
110!! other for the indices of values larger than the pivot that we might
111!! still need later on. It iterates until it can bring the number of
112!! values in ILOWT to exactly NORD, and then uses an insertion sort to
113!! rank this set, since it is supposedly small. At all times, the NORD
114!! first values in ILOWT correspond to distinct values of the input
115!! array.
116!!
117!! \code{.f90} subroutine UNIINV (XVALT, IGOEST) \endcode
118!!
119!! Inverse ranking of an array, with
120!! removal of duplicate entries The routine is similar to pure merge-sort
121!! ranking, but on the last pass, it sets indices in IGOEST to the rank
122!! of the original value in an ordered set with duplicates removed. For
123!! performance reasons, the first 2 passes are taken out of the standard
124!! loop, and use dedicated coding.
125!!
126!! \code{.f90} subroutine MULCNT (XVALT, IMULT) \endcode
127!!
128!! Gives, for each array value, its
129!! multiplicity The number of times that a value appears in the array is
130!! computed by using inverse ranking, counting for each rank the number
131!! of values that ``collide'' to this rank, and returning this sum to the
132!! locations in the original set. Uses subroutine UNIINV.
133!!
134!! <b> Random permutation: an interesting use of ranking </b>
135!!
136!! A variation of the following problem was raised on the internet
137!! sci.math.num-analysis news group: Given an array, I would like to find
138!! a random permutation of this array that I could control with a
139!! "nearbyness" parameter so that elements stay close to their initial
140!! locations. The "nearbyness" parameter ranges from 0 to 1, with 0
141!! such that no element moves from its initial location, and 1 such that
142!! the permutation is fully random.
143!!
144!! \code{.f90} subroutine CTRPER (XVALT, PCLS) \endcode
145!!
146!! Permute array XVALT randomly, but
147!! leaving elements close to their initial locations The routine takes
148!! the 1...size(XVALT) index array as real values, takes a combination of
149!! these values and of random values as a perturbation of the index
150!! array, and sorts the initial set according to the ranks of these
151!! perturbated indices. The relative proportion of initial order and
152!! random order is 1-PCLS / PCLS, thus when PCLS = 0, there is no change
153!! in the order whereas the new order is fully random when PCLS = 1. Uses
154!! subroutine MRGRNK.
155!!
156!! The above solution found another application when I was asked the
157!! following question: I am given two arrays, representing parents'
158!! incomes and their children's incomes, but I do not know which parents
159!! correspond to which children. I know from an independent source the
160!! value of the correlation coefficient between the incomes of the
161!! parents and of their children. I would like to pair the elements of
162!! these arrays so that the given correlation coefficient is attained,
163!! i.e. to reconstruct a realistic dataset, though very likely not to be
164!! the true one.
165!!
166!! \code{.f90} program GIVCOR \endcode
167!!
168!! Given two arrays of equal length of unordered values,
169!! find a "matching value" in the second array for each value in the
170!! first so that the global correlation coefficient reaches exactly a
171!! given target The routine first sorts the two arrays, so as to get the
172!! match of maximum possible correlation. It then iterates, applying the
173!! random permutation algorithm of controlled disorder ctrper to the
174!! second array. When the resulting correlation goes beyond (lower than)
175!! the target correlation, one steps back and reduces the disorder
176!! parameter of the permutation. When the resulting correlation lies
177!! between the current one and the target, one replaces the array with
178!! the newly permuted one. When the resulting correlation increases from
179!! the current value, one increases the disorder parameter. That way, the
180!! target correlation is approached from above, by a controlled increase
181!! in randomness. Since full randomness leads to zero correlation, the
182!! iterations meet the desired coefficient at some point. It may be noted
183!! that there could be some cases when one would get stuck in a sort of
184!! local minimum, where local perturbations cannot further reduce the
185!! correlation and where global ones lead to overpass the target. It
186!! seems easier to restart the program with a different seed when this
187!! occurs than to design an avoidance scheme. Also, should a negative
188!! correlation be desired, the program should be modified to start with
189!! one array in reverse order with respect to the other, i.e. coorelation
190!! as close to -1 as possible.
191!!
192!! <b> Full sorting </b>
193!!
194!! \code{.f90} subroutine INSSOR (XVALT) \endcode
195!!
196!! Sorts XVALT into increasing order (Insertion
197!! sort) This subroutine uses insertion sort. It does not use any work
198!! array and is faster when XVALT is of very small size (< 20), or
199!! already almost sorted, but worst case behavior (intially inverse
200!! sorted) can easily happen. In most cases, the quicksort or merge sort
201!! method is faster.
202!!
203!! \code{.f90} subroutine REFSOR (XVALT) \endcode
204!!
205!! Sorts XVALT into increasing order (Quick
206!! sort) This version is not optimized for performance, and is thus not
207!! as difficult to read as some other ones. This subroutine uses
208!! quicksort in a recursive implementation, and insertion sort for the
209!! last steps with small subsets. It does not use any work array
210!!
211!! <b> Partial sorting </b>
212!!
213!! \code{.f90} subroutine INSPAR (XVALT, NORD) \endcode
214!!
215!! Sorts partially XVALT, bringing the
216!! NORD lowest values at the begining of the array. This subroutine uses
217!! insertion sort, limiting insertion to the first NORD values. It does
218!! not use any work array and is faster when NORD is very small (2-5),
219!! but worst case behavior can happen fairly probably (initially inverse
220!! sorted). In many cases, the refined quicksort method is faster.
221!!
222!! \code{.f90} function FNDNTH (XVALT, NORD) \endcode
223!!
224!! Finds out and returns the NORDth value
225!! in XVALT (ascending order) This subroutine uses insertion sort,
226!! limiting insertion to the first NORD values, and even less when one
227!! can know that the value that is considered will not be the NORDth. It
228!! uses only a work array of size NORD and is faster when NORD is very
229!! small (2-5), but worst case behavior can happen fairly probably
230!! (initially inverse sorted). In many cases, the refined quicksort
231!! method implemented by VALNTH / INDNTH is faster, though much more
232!! difficult to read and understand.
233!!
234!! \code{.f90} function VALNTH (XVALT, NORD) \endcode
235!!
236!! Finds out and returns the NORDth value
237!! in XVALT (ascending order) This subroutine simply calls INDNTH.
238!!
239!! \code{.f90} function VALMED (XVALT) \endcode
240!!
241!! Finds out and returns the median(((Size(XVALT)+1))/2th value) of XVALT This routine uses the recursive
242!! procedure described in Knuth, The Art of Computer Programming, vol. 3,
243!! 5.3.3 - This procedure is linear in time, and does not require to be
244!! able to interpolate in the set as the one used in VALNTH/INDNTH. It
245!! also has better worst case behavior than VALNTH/INDNTH, and is about
246!! 20% faster in average for random uniformly distributed values.
247!!
248!! \code{.f90} function OMEDIAN (XVALT) \endcode
249!!
250!! It is a modified version of VALMED that
251!! provides the average between the two middle values in the case
252!! Size(XVALT) is even.
253!!
254!! <b> Unique sorting </b>
255!!
256!! \code{.f90} subroutine UNISTA (XVALT, NUNI) \endcode
257!!
258!! Removes duplicates from an array This
259!! subroutine uses merge sort unique inverse ranking. It leaves in the
260!! initial set only those entries that are unique, packing the array, and
261!! leaving the order of the retained values unchanged.
262!> \authors Michel Olagnon
263!> \date 2000-2012
264!> \changelog
265!! - Matthias Cuntz, Apr 2014
266!! - adapted to UFZ library
267!! - one module, cleaned all warnings
268!! - Juliane Mai, Nov 2014
269!! - replaced floating comparison by ne(), eq(), etc. from mo_utils
270!! - Matthias Cuntz, Jul 2015
271!! - median -> omedian
272!> \copyright Copyright 2005-\today, the CHS Developers, Sabine Attinger: All rights reserved.
273!! FORCES is released under the LGPLv3+ license \license_note
275
276 USE mo_kind, ONLY : i4, sp, dp
277 USE mo_utils, ONLY : ne, eq, le
278
279 IMPLICIT NONE
280
281 ! Public routines
282 public :: sort ! alias for refsor
283 public :: sort_index ! wrapper for mrgrnk
284
285 public :: ctrper
286 public :: fndnth
287 public :: indmed
288 public :: indnth
289 public :: inspar
290 public :: inssor
291 public :: omedian
292 public :: mrgref
293 public :: mrgrnk
294 public :: mulcnt
295 public :: rapknr
296 public :: refpar
297 public :: refsor
298 public :: rinpar
299 public :: rnkpar
300 public :: uniinv
301 public :: unipar
302 public :: unirnk
303 public :: unista
304 public :: valmed
305 public :: valnth
306
307 ! aliases/wrapper
308
309 !> \brief Sorts the input array in ascending order.
310 !> \param[in,out] "real(sp/dp) :: arr(:)" On input: unsorted 1D-array\n
311 !! On output: ascendingly sorted input array
312 interface sort
313 module procedure d_refsor, r_refsor, i_refsor, c_refsor
314 end interface sort
315
316 !> \brief Gives the indeces that would sort an array in ascending order.
317 !> \param[in] "real(sp/dp) :: arr(:)" Unsorted 1D-array
318 !> \return integer(i4) :: indices(:) &mdash; Indices that would sort arr in ascending order
319 interface sort_index
320 module procedure sort_index_dp, sort_index_sp, sort_index_i4
321 end interface sort_index
322
323 !> \brief Random permutation ranking.
324
325 !> \details
326 !! Permute array XVALT randomly, but
327 !! leaving elements close to their initial locations The routine takes
328 !! the 1...size(XVALT) index array as real values, takes a combination of
329 !! these values and of random values as a perturbation of the index
330 !! array, and sorts the initial set according to the ranks of these
331 !! perturbated indices. The relative proportion of initial order and
332 !! random order is 1-PCLS / PCLS, thus when PCLS = 0, there is no change
333 !! in the order whereas the new order is fully random when PCLS = 1. Uses
334 !! subroutine MRGRNK.
335 !!
336 !! The above solution found another application when I was asked the
337 !! following question: I am given two arrays, representing parents'
338 !! incomes and their children's incomes, but I do not know which parents
339 !! correspond to which children. I know from an independent source the
340 !! value of the correlation coefficient between the incomes of the
341 !! parents and of their children. I would like to pair the elements of
342 !! these arrays so that the given correlation coefficient is attained,
343 !! i.e. to reconstruct a realistic dataset, though very likely not to be
344 !! the true one.
345
346 !> \param[inout] "integer(i4)/real(sp,dp), dimension(:) :: XVALT" Array to be randomly permuted.
347 !> \param[in] "integer(i4)/real(sp,dp) :: PCLS" Nearbyness of permutation.
348
349 interface ctrper
350 module procedure d_ctrper, r_ctrper, i_ctrper
351 end interface ctrper
352
353 !> \brief Find N-th value in array from insertion sort
354
355 !> \details
356 !! Finds out and returns the NORDth value
357 !! in XVALT (ascending order). This subroutine uses insertion sort,
358 !! limiting insertion to the first NORD values, and even less when one
359 !! can know that the value that is considered will not be the NORDth. It
360 !! uses only a work array of size NORD and is faster when NORD is very
361 !! small (2-5), but worst case behavior can happen fairly probably
362 !! (initially inverse sorted). In many cases, the refined quicksort
363 !! method implemented by VALNTH / INDNTH is faster, though much more
364 !! difficult to read and understand.
365
366 !> \param[in] "integer(i4)/real(sp,dp), dimension(:) :: XVALT" Array to be ranked.
367 !> \param[in] "integer(i4) :: NORD" Number of ranked elements.
368 !> \retval "integer(i4)/real(sp,dp) :: FNDNTH" Value of NORDth rank.
369
370 interface fndnth
371 module procedure d_fndnth, r_fndnth, i_fndnth
372 end interface fndnth
373
374 !> \brief Median index of skewed-pivot with quicksort ranking.
375
376 !> \details
377 !! Returns the index of the median
378 !! `(((Size(XVALT)+1))/2th value)` of XVALT This routine uses the recursive
379 !! procedure described in Knuth, The Art of Computer Programming, vol. 3,
380 !! 5.3.3 - This procedure is linear in time, and does not require to be
381 !! able to interpolate in the set as the one used in INDNTH. It also has
382 !! better worst case behavior than INDNTH, but is about 10% slower in
383 !! average for random uniformly distributed values.\n
384 !! Note that in Orderpack 1.0, this routine was a Function procedure, and
385 !! is now changed to a Subroutine.
386
387 !> \param[in] "integer(i4)/real(sp,dp), dimension(:) :: XVALT" Array to be ranked.
388 !> \param[out] "integer(i4) :: INDM" Index of Median.
389
390 interface indmed
391 module procedure d_indmed, r_indmed, i_indmed
392 end interface indmed
393
394 !> \brief Nth index of skewed-pivot with quicksort ranking.
395
396 !> \details
397 !! Returns the index of the NORDth
398 !! value of XVALT (in increasing order). This routine uses a pivoting
399 !! strategy such as the one of finding the median based on the quicksort
400 !! algorithm, but we skew the pivot choice to try to bring it to NORD as
401 !! fast as possible. It uses 2 temporary arrays, one where it stores the
402 !! indices of the values smaller than the pivot, and the other for the
403 !! indices of values larger than the pivot that we might still need later
404 !! on. It iterates until it can bring the number of values in ILOWT to
405 !! exactly NORD, and then takes out the original index of the maximum
406 !! value in this set.
407
408 !> \param[in] "integer(i4)/real(sp,dp), dimension(:) :: XVALT" Array to be ranked.
409 !> \param[in] "integer(i4) :: NORD" Number of ranked elements.
410 !> \retval "integer(i4) :: INDNTH" Index of NORDth rank.
411
412 interface indnth
413 module procedure d_indnth, r_indnth, i_indnth
414 end interface indnth
415
416 !> \brief Partial insertion sort ranking,
417
418 !> \details
419 !! Sorts partially XVALT, bringing the
420 !! NORD lowest values at the begining of the array. This subroutine uses
421 !! insertion sort, limiting insertion to the first NORD values. It does
422 !! not use any work array and is faster when NORD is very small (2-5),
423 !! but worst case behavior can happen fairly probably (initially inverse
424 !! sorted). In many cases, the refined quicksort method is faster.
425
426 !> \param[inout] "integer(i4)/real(sp,dp), dimension(:) :: XVALT" Array to be ranked.
427 !> \param[in] "integer(i4) :: NORD" Number of ranked elements from beginning of array.
428
429 interface inspar
430 module procedure d_inspar, r_inspar, i_inspar
431 end interface inspar
432
433 !> \brief Insertion sort ranking
434
435 !> \details
436 !! Sorts XVALT into increasing order (Insertion
437 !! sort) This subroutine uses insertion sort. It does not use any work
438 !! array and is faster when XVALT is of very small size (< 20), or
439 !! already almost sorted, but worst case behavior (intially inverse
440 !! sorted) can easily happen. In most cases, the quicksort or merge sort
441 !! method is faster.
442
443 !> \param[inout] "integer(i4)/real(sp,dp), dimension(:) :: XVALT" Array to be ranked.
444
445 interface inssor
446 module procedure d_inssor, r_inssor, i_inssor, c_inssor
447 end interface inssor
448
449 !> \brief Find median value of array (case for even elements)
450
451 !> \details
452 !! It is a modified version of VALMED that
453 !! provides the average between the two middle values in the case
454 !! Size(XVALT) is even.
455
456 !> \param[in] "integer(i4)/real(sp,dp), dimension(:) :: XVALT" Array to be ranked.
457 !> \retval "integer(i4)/real(sp,dp) :: OMEDIAN" Value of median.
458
459 interface omedian
460 module procedure d_median, r_median, i_median
461 end interface omedian
462
463 !> \brief Merge-sort ranking (unoptimized)
464
465 !> \details
466 !! Ranks array XVALT into index array
467 !! IRNGT, using merge-sort. This version is not optimized for performance,
468 !! and is thus not as difficult to read as the previous one.
469
470 !> \param[in] "integer(i4)/real(sp,dp), dimension(:) :: XVALT" Array to be ranked.
471 !> \retval "integer(i4), dimension(:) :: IRNGT" Index of rank.
472
473 interface mrgref
474 module procedure d_mrgref, r_mrgref, i_mrgref
475 end interface mrgref
476
477 !> \brief Merge-sort ranking
478
479 !> \details
480 !! Ranks array XVALT into index array IRNGT, using merge-sort.\n
481 !! For performance reasons, the first 2 passes are taken out of the
482 !! standard loop, and use dedicated coding.
483
484 !> \param[in] "integer(i4)/real(sp,dp), dimension(:) :: XVALT" Array to be ranked.
485 !> \retval "integer(i4), dimension(:) :: IRNGT" Index of rank.
486
487 interface mrgrnk
488 module procedure d_mrgrnk, r_mrgrnk, i_mrgrnk, c_mrgrnk
489 end interface mrgrnk
490
491 !> \brief Multiplicity of array values.
492
493 !> \details
494 !! Gives, for each array value, its
495 !! multiplicity. The number of times that a value appears in the array is
496 !! computed by using inverse ranking, counting for each rank the number
497 !! of values that ``collide'' to this rank, and returning this sum to the
498 !! locations in the original set. Uses subroutine UNIINV.
499
500 !> \param[in] "integer(i4)/real(sp,dp), dimension(:) :: XVALT" Array to be ranked.
501 !> \param[out] "integer(i4), dimension(:) :: IMULT" Multiplicity of array values.
502
503
504 interface mulcnt
505 module procedure d_mulcnt, r_mulcnt, i_mulcnt
506 end interface mulcnt
507
508 !> \brief Skewed-pivot with quicksort ranking (reversed).
509
510 !> \details
511 !! Same as `RNKPAR`, but in
512 !! decreasing order (RAPKNR = RNKPAR spelt backwards).
513
514 !> \param[in] "integer(i4)/real(sp,dp), dimension(:) :: XVALT" Array to be ranked.
515 !> \param[in] "integer(i4) :: NORD" Number of ranked elements.
516 !> \retval "integer(i4), dimension(:) :: IRNGT" Index of rank.
517
518 interface rapknr
519 module procedure d_rapknr, r_rapknr, i_rapknr
520 end interface rapknr
521
522 !> \brief Skewed-pivot with quicksort ranking (unoptimized).
523
524 !> \details
525 !! Ranks partially XVALT by IRNGT,
526 !! up to order NORD. This version is not optimized for performance, and is
527 !! thus not as difficult to read as some other ones. It uses a pivoting
528 !! strategy such as the one of finding the median based on the quicksort
529 !! algorithm. It uses a temporary array, where it stores the partially
530 !! ranked indices of the values. It iterates until it can bring the
531 !! number of values lower than the pivot to exactly NORD, and then uses
532 !! an insertion sort to rank this set, since it is supposedly small.
533
534 !> \param[in] "integer(i4)/real(sp,dp), dimension(:) :: XVALT" Array to be ranked.
535 !> \param[in] "integer(i4) :: NORD" Number of ranked elements.
536 !> \retval "integer(i4), dimension(:) :: IRNGT" Index of rank.
537
538 interface refpar
539 module procedure d_refpar, r_refpar, i_refpar
540 end interface refpar
541
542 !> \brief Quicksort ranking, with insertion sort at last step (unoptimized)
543
544 !> \details
545 !! Sorts XVALT into increasing order (Quick
546 !! sort). This version is not optimized for performance, and is thus not
547 !! as difficult to read as some other ones. This subroutine uses
548 !! quicksort in a recursive implementation, and insertion sort for the
549 !! last steps with small subsets. It does not use any work array
550
551 !> \param[inout] "integer(i4)/real(sp,dp), dimension(:) :: XVALT" Array to be ranked.
552
553 interface refsor
554 module procedure d_refsor, r_refsor, i_refsor, c_refsor
555 end interface refsor
556
557 !> \brief Insertion sort ranking (unoptimized).
558
559 !> \details
560 !! Ranks partially XVALT by IRNGT,
561 !! up to order NORD This version is not optimized for performance, and is
562 !! thus not as difficult to read as some other ones. It uses insertion
563 !! sort, limiting insertion to the first NORD values. It does not use any
564 !! work array and is faster when NORD is very small (2-5), but worst case
565 !! behavior (intially inverse sorted) can easily happen. In many cases,
566 !! refined quicksort method is faster.
567
568 !> \param[in] "integer(i4)/real(sp,dp), dimension(:) :: XVALT" Array to be ranked.
569 !> \param[in] "integer(i4) :: NORD" Number of ranked elements.
570 !> \retval "integer(i4), dimension(:) :: IRNGT" Index of rank.
571
572 interface rinpar
573 module procedure d_rinpar, r_rinpar, i_rinpar
574 end interface rinpar
575
576 !> \brief Skewed-pivot with quicksort ranking.
577
578 !> \details
579 !! Ranks partially XVALT by IRNGT,
580 !! up to order NORD (refined for speed). This routine uses a pivoting
581 !! strategy such as the one of finding the median based on the quicksort
582 !! algorithm, but we skew the pivot choice to try to bring it to NORD as
583 !! fast as possible. It uses 2 temporary arrays, one where it stores the
584 !! indices of the values smaller than the pivot, and the other for the
585 !! indices of values larger than the pivot that we might still need later
586 !! on. It iterates until it can bring the number of values in ILOWT to
587 !! exactly NORD, and then uses an insertion sort to rank this set, since
588 !! it is supposedly small.
589
590 !> \param[in] "integer(i4)/real(sp,dp), dimension(:) :: XVALT" Array to be ranked.
591 !> \param[in] "integer(i4) :: NORD" Number of ranked elements.
592 !> \retval "integer(i4), dimension(:) :: IRNGT" Index of rank.
593
594 interface rnkpar
595 module procedure d_rnkpar, r_rnkpar, i_rnkpar
596 end interface rnkpar
597
598 !> \brief Merge-sort ranking, with removal of duplicate entries (reversed).
599
600 !> \details
601 !! Inverse ranking of an array, with
602 !! removal of duplicate entries. The routine is similar to pure merge-sort
603 !! ranking, but on the last pass, it sets indices in IGOEST to the rank
604 !! of the original value in an ordered set with duplicates removed. For
605 !! performance reasons, the first 2 passes are taken out of the standard
606 !! loop, and use dedicated coding.
607
608 !> \param[in] "integer(i4)/real(sp,dp), dimension(:) :: XVALT" Array to be ranked.
609 !> \param[out] "integer(i4), dimension(:) :: IGOEST" Index of rank.
610
611 interface uniinv
612 module procedure d_uniinv, r_uniinv, i_uniinv
613 end interface uniinv
614 interface nearless
615 module procedure d_nearless, r_nearless, i_nearless
616 end interface nearless
617
618 !> \brief Partial quicksort/insertion sort ranking, with removal of duplicate entries.
619
620 !> \details
621 !! Ranks partially XVALT by IRNGT,
622 !! up to order NORD at most, removing duplicate entries. This routine uses
623 !! a pivoting strategy such as the one of finding the median based on the
624 !! quicksort algorithm, but we skew the pivot choice to try to bring it
625 !! to NORD as quickly as possible. It uses 2 temporary arrays, one where
626 !! it stores the indices of the values smaller than the pivot, and the
627 !! other for the indices of values larger than the pivot that we might
628 !! still need later on. It iterates until it can bring the number of
629 !! values in ILOWT to exactly NORD, and then uses an insertion sort to
630 !! rank this set, since it is supposedly small. At all times, the NORD
631 !! first values in ILOWT correspond to distinct values of the input
632 !! array.
633
634 !> \param[in] "integer(i4)/real(sp,dp), dimension(:) :: XVALT" Array to be ranked.
635 !> \param[in] "integer(i4) :: NORD" Rank of quicksort ranking.
636 !> \param[out] "integer(i4), dimension(:) :: IRNGT" Index of rank.
637
638 interface unipar
639 module procedure d_unipar, r_unipar, i_unipar
640 end interface unipar
641
642 !> \brief Merge-sort ranking, with removal of duplicate entries.
643
644 !> \details
645 !! Ranks an array, removing
646 !! duplicate entries (uses merge sort). The routine is similar to pure
647 !! merge-sort ranking, but on the last pass, it discards indices that
648 !! correspond to duplicate entries. For performance reasons, the first 2
649 !! passes are taken out of the standard loop, and use dedicated coding.
650
651 !> \param[in] "integer(i4)/real(sp,dp), dimension(:) :: XVALT" Array to be ranked.
652 !> \param[out] "integer(i4) :: NUNI" Rank of last number after duplicates removed.
653 !> \param[out] "integer(i4), dimension(:) :: IRNGT" Index of rank.
654
655 interface unirnk
656 module procedure d_unirnk, r_unirnk, i_unirnk
657 end interface unirnk
658
659 !> \brief Merge-sort unique inverse ranking.
660
661 !> \details
662 !! Removes duplicates from an array This
663 !! subroutine uses merge sort unique inverse ranking. It leaves in the
664 !! initial set only those entries that are unique, packing the array, and
665 !! leaving the order of the retained values unchanged.
666
667 !> \param[inout] "integer(i4)/real(sp,dp), dimension(:) :: XVALT" Array to be ranked.
668 !> \param[out] "integer(i4) :: NUNI" Rank of last number after duplicates removed.
669
670 interface unista
671 module procedure d_unista, r_unista, i_unista
672 end interface unista
673
674 !> \brief Find median value of array
675
676 !> \details
677 !! Finds out and returns the median(((Size(XVALT)+1))/2th value) of XVALT This routine uses the recursive
678 !! procedure described in Knuth, The Art of Computer Programming, vol. 3,
679 !! 5.3.3 - This procedure is linear in time, and does not require to be
680 !! able to interpolate in the set as the one used in VALNTH/INDNTH. It
681 !! also has better worst case behavior than VALNTH/INDNTH, and is about
682 !! 20% faster in average for random uniformly distributed values.
683
684 !> \param[in] "integer(i4)/real(sp,dp), dimension(:) :: XVALT" Array to be ranked.
685 !> \retval "integer(i4)/real(sp,dp) :: VALMED" Value of median.
686
687 interface valmed
688 module procedure d_valmed, r_valmed, i_valmed
689 end interface valmed
690
691 !> \brief Find N-th value in array from quicksort
692
693 !> \details
694 !! Finds out and returns the NORDth value
695 !! in XVALT (ascending order). This subroutine simply calls INDNTH.
696
697 !> \param[in] "integer(i4)/real(sp,dp), dimension(:) :: XVALT" Array to be ranked.
698 !> \param[in] "integer(i4) :: NORD" Number of ranked elements.
699 !> \retval "integer(i4)/real(sp,dp) :: VALNTH" Value of NORDth rank.
700
701 interface valnth
702 module procedure d_valnth, r_valnth, i_valnth
703 end interface valnth
704
705 private :: r_ctrper, i_ctrper, d_ctrper
706 private :: r_fndnth, i_fndnth, d_fndnth
707 private :: r_indmed, i_indmed, d_indmed
708 private :: r_indnth, i_indnth, d_indnth
709 private :: r_inspar, i_inspar, d_inspar
710 private :: r_inssor, i_inssor, d_inssor, c_inssor
711 private :: r_median, i_median, d_median
712 private :: r_mrgref, i_mrgref, d_mrgref
713 private :: r_mrgrnk, i_mrgrnk, d_mrgrnk
714 private :: r_mulcnt, i_mulcnt, d_mulcnt
715 private :: r_nearless, i_nearless, d_nearless, nearless
716 private :: r_rapknr, i_rapknr, d_rapknr
717 private :: r_refpar, i_refpar, d_refpar
718 private :: r_refsor, i_refsor, d_refsor, c_refsor
719 private :: r_rinpar, i_rinpar, d_rinpar
720 private :: r_rnkpar, i_rnkpar, d_rnkpar
721 private :: r_subsor, i_subsor, d_subsor, c_subsor
722 private :: r_uniinv, i_uniinv, d_uniinv
723 private :: r_unipar, i_unipar, d_unipar
724 private :: r_unirnk, i_unirnk, d_unirnk
725 private :: r_unista, i_unista, d_unista
726 private :: r_valmed, i_valmed, d_valmed
727 private :: r_valnth, i_valnth, d_valnth
728 private :: r_med, i_med, d_med
729
730 PRIVATE
731
732 Integer(kind = i4), Allocatable, Dimension(:), Save :: IDONT
733
734CONTAINS
735
736 ! ------------------------------------------------------------------
737
738 FUNCTION sort_index_dp(arr)
739
740 IMPLICIT NONE
741
742 REAL(dp), DIMENSION(:), INTENT(IN) :: arr
743 INTEGER(i4), DIMENSION(size(arr)) :: sort_index_dp
744
745 call mrgrnk(arr, sort_index_dp)
746
747 END FUNCTION sort_index_dp
748
749 FUNCTION sort_index_sp(arr)
750
751 IMPLICIT NONE
752
753 REAL(sp), DIMENSION(:), INTENT(IN) :: arr
754 INTEGER(i4), DIMENSION(size(arr)) :: sort_index_sp
755
756 call mrgrnk(arr, sort_index_sp)
757
758 END FUNCTION sort_index_sp
759
760 FUNCTION sort_index_i4(arr)
761
762 IMPLICIT NONE
763
764 integer(i4), DIMENSION(:), INTENT(IN) :: arr
765 INTEGER(i4), DIMENSION(size(arr)) :: sort_index_i4
766
767 call mrgrnk(arr, sort_index_i4)
768
769 END FUNCTION sort_index_i4
770
771
772 ! ------------------------------------------------------------------
773
774 Subroutine d_ctrper (XDONT, PCLS)
775 ! Permute array XVALT randomly, but leaving elements close
776 ! to their initial locations (nearbyness is controled by PCLS).
777 ! _________________________________________________________________
778 ! The routine takes the 1...size(XVALT) index array as real
779 ! values, takes a combination of these values and of random
780 ! values as a perturbation of the index array, and sorts the
781 ! initial set according to the ranks of these perturbated indices.
782 ! The relative proportion of initial order and random order
783 ! is 1-PCLS / PCLS, thus when PCLS = 0, there is no change in
784 ! the order whereas the new order is fully random when PCLS = 1.
785 ! Michel Olagnon - May 2000.
786 ! _________________________________________________________________
787 ! __________________________________________________________
788 real(kind = dp), Dimension (:), Intent (InOut) :: xdont
789 Real(kind = dp), Intent (In) :: pcls
790 ! __________________________________________________________
791 !
792 Real(kind = dp), Dimension (Size(XDONT)) :: xindt
793 Integer(kind = i4), Dimension (Size(XDONT)) :: JWRKT
794 Real(kind = dp) :: pwrk
795 Integer(kind = i4) :: I
796 Real(kind = dp), Dimension (Size(XDONT)) :: ii
797 !
798 Call random_number (xindt(:))
799 pwrk = min(max(0.0_dp, pcls), 1.0_dp)
800 xindt = real(Size(xdont), dp) * xindt
801 forall(i = 1 : size(xdont)) ii(i) = real(i, dp) ! for gnu compiler to be initialised
802 xindt = pwrk * xindt + (1.0_dp - pwrk) * ii
803 Call mrgrnk (xindt, jwrkt)
804 xdont = xdont(jwrkt)
805 !
806 End Subroutine d_ctrper
807
808 Subroutine r_ctrper (XDONT, PCLS)
809 ! Permute array XVALT randomly, but leaving elements close
810 ! to their initial locations (nearbyness is controled by PCLS).
811 ! _________________________________________________________________
812 ! The routine takes the 1...size(XVALT) index array as real
813 ! values, takes a combination of these values and of random
814 ! values as a perturbation of the index array, and sorts the
815 ! initial set according to the ranks of these perturbated indices.
816 ! The relative proportion of initial order and random order
817 ! is 1-PCLS / PCLS, thus when PCLS = 0, there is no change in
818 ! the order whereas the new order is fully random when PCLS = 1.
819 ! Michel Olagnon - May 2000.
820 ! _________________________________________________________________
821 ! _________________________________________________________
822 Real(kind = sp), Dimension (:), Intent (InOut) :: xdont
823 Real(kind = sp), Intent (In) :: pcls
824 ! __________________________________________________________
825 !
826 Real(kind = sp), Dimension (Size(XDONT)) :: xindt
827 Integer(kind = i4), Dimension (Size(XDONT)) :: JWRKT
828 Real(kind = sp) :: pwrk
829 Integer(kind = i4) :: I
830 Real(kind = sp), Dimension (Size(XDONT)) :: ii
831 !
832 Call random_number (xindt(:))
833 pwrk = min(max(0.0, pcls), 1.0)
834 xindt = real(Size(xdont), sp) * xindt
835 forall(i = 1 : size(xdont)) ii(i) = real(i, sp) ! for gnu compiler to be initialised
836 xindt = pwrk * xindt + (1.0 - pwrk) * ii
837 Call mrgrnk (xindt, jwrkt)
838 xdont = xdont(jwrkt)
839 !
840 End Subroutine r_ctrper
841
842 Subroutine i_ctrper (XDONT, PCLS)
843 ! Permute array XVALT randomly, but leaving elements close
844 ! to their initial locations (nearbyness is controled by PCLS).
845 ! _________________________________________________________________
846 ! The routine takes the 1...size(XVALT) index array as real
847 ! values, takes a combination of these values and of random
848 ! values as a perturbation of the index array, and sorts the
849 ! initial set according to the ranks of these perturbated indices.
850 ! The relative proportion of initial order and random order
851 ! is 1-PCLS / PCLS, thus when PCLS = 0, there is no change in
852 ! the order whereas the new order is fully random when PCLS = 1.
853 ! Michel Olagnon - May 2000.
854 ! _________________________________________________________________
855 ! __________________________________________________________
856 Integer(kind = i4), Dimension (:), Intent (InOut) :: XDONT
857 Real(kind = sp), Intent (In) :: pcls
858 ! __________________________________________________________
859 !
860 Real(kind = sp), Dimension (Size(XDONT)) :: xindt
861 Integer(kind = i4), Dimension (Size(XDONT)) :: JWRKT
862 Real(kind = sp) :: pwrk
863 Integer(kind = i4) :: I
864 Real(kind = sp), Dimension (Size(XDONT)) :: ii
865 !
866 Call random_number (xindt(:))
867 pwrk = min(max(0.0, pcls), 1.0)
868 xindt = real(Size(xdont), sp) * xindt
869 forall(i = 1 : size(xdont)) ii(i) = real(i, sp) ! for gnu compiler to be initialised
870 xindt = pwrk * xindt + (1.0 - pwrk) * ii
871 Call mrgrnk(xindt, jwrkt)
872 xdont = xdont(jwrkt)
873 !
874 End Subroutine i_ctrper
875
876 Function d_fndnth (XDONT, NORD) Result (FNDNTH)
877 ! Return NORDth value of XDONT, i.e fractile of order NORD/SIZE(XDONT).
878 ! ______________________________________________________________________
879 ! This subroutine uses insertion sort, limiting insertion
880 ! to the first NORD values. It is faster when NORD is very small (2-5),
881 ! and it requires only a workarray of size NORD and type of XDONT,
882 ! but worst case behavior can happen fairly probably (initially inverse
883 ! sorted). In many cases, the refined quicksort method is faster.
884 ! Michel Olagnon - Aug. 2000
885 ! __________________________________________________________
886 ! __________________________________________________________
887 real(Kind = dp), Dimension (:), Intent (In) :: xdont
888 real(Kind = dp) :: fndnth
889 Integer(kind = i4), Intent (In) :: NORD
890 ! __________________________________________________________
891 real(Kind = dp), Dimension (NORD) :: xwrkt
892 real(Kind = dp) :: xwrk, xwrk1
893 !
894 !
895 Integer(kind = i4) :: ICRS, IDCR, ILOW, NDON
896 !
897 xwrkt(1) = xdont(1)
898 Do icrs = 2, nord
899 xwrk = xdont(icrs)
900 Do idcr = icrs - 1, 1, - 1
901 If (xwrk >= xwrkt(idcr)) Exit
902 xwrkt(idcr + 1) = xwrkt(idcr)
903 End Do
904 xwrkt(idcr + 1) = xwrk
905 End Do
906 !
907 ndon = SIZE (xdont)
908 xwrk1 = xwrkt(nord)
909 ilow = 2 * nord - ndon
910 Do icrs = nord + 1, ndon
911 If (xdont(icrs) < xwrk1) Then
912 xwrk = xdont(icrs)
913 Do idcr = nord - 1, max(1, ilow), - 1
914 If (xwrk >= xwrkt(idcr)) Exit
915 xwrkt(idcr + 1) = xwrkt(idcr)
916 End Do
917 xwrkt(idcr + 1) = xwrk
918 xwrk1 = xwrkt(nord)
919 End If
920 ilow = ilow + 1
921 End Do
922 fndnth = xwrk1
923
924 !
925 End Function d_fndnth
926
927 Function r_fndnth (XDONT, NORD) Result (FNDNTH)
928 ! Return NORDth value of XDONT, i.e fractile of order NORD/SIZE(XDONT).
929 ! ______________________________________________________________________
930 ! This subroutine uses insertion sort, limiting insertion
931 ! to the first NORD values. It is faster when NORD is very small (2-5),
932 ! and it requires only a workarray of size NORD and type of XDONT,
933 ! but worst case behavior can happen fairly probably (initially inverse
934 ! sorted). In many cases, the refined quicksort method is faster.
935 ! Michel Olagnon - Aug. 2000
936 ! __________________________________________________________
937 ! _________________________________________________________
938 Real(kind = sp), Dimension (:), Intent (In) :: xdont
939 Real(kind = sp) :: fndnth
940 Integer(kind = i4), Intent (In) :: NORD
941 ! __________________________________________________________
942 Real(kind = sp), Dimension (NORD) :: xwrkt
943 Real(kind = sp) :: xwrk, xwrk1
944 !
945 !
946 Integer(kind = i4) :: ICRS, IDCR, ILOW, NDON
947 !
948 xwrkt(1) = xdont(1)
949 Do icrs = 2, nord
950 xwrk = xdont(icrs)
951 Do idcr = icrs - 1, 1, - 1
952 If (xwrk >= xwrkt(idcr)) Exit
953 xwrkt(idcr + 1) = xwrkt(idcr)
954 End Do
955 xwrkt(idcr + 1) = xwrk
956 End Do
957 !
958 ndon = SIZE (xdont)
959 xwrk1 = xwrkt(nord)
960 ilow = 2 * nord - ndon
961 Do icrs = nord + 1, ndon
962 If (xdont(icrs) < xwrk1) Then
963 xwrk = xdont(icrs)
964 Do idcr = nord - 1, max(1, ilow), - 1
965 If (xwrk >= xwrkt(idcr)) Exit
966 xwrkt(idcr + 1) = xwrkt(idcr)
967 End Do
968 xwrkt(idcr + 1) = xwrk
969 xwrk1 = xwrkt(nord)
970 End If
971 ilow = ilow + 1
972 End Do
973 fndnth = xwrk1
974
975 !
976 End Function r_fndnth
977
978 Function i_fndnth (XDONT, NORD) Result (FNDNTH)
979 ! Return NORDth value of XDONT, i.e fractile of order NORD/SIZE(XDONT).
980 ! ______________________________________________________________________
981 ! This subroutine uses insertion sort, limiting insertion
982 ! to the first NORD values. It is faster when NORD is very small (2-5),
983 ! and it requires only a workarray of size NORD and type of XDONT,
984 ! but worst case behavior can happen fairly probably (initially inverse
985 ! sorted). In many cases, the refined quicksort method is faster.
986 ! Michel Olagnon - Aug. 2000
987 ! __________________________________________________________
988 ! __________________________________________________________
989 Integer(kind = i4), Dimension (:), Intent (In) :: XDONT
990 Integer(kind = i4) :: fndnth
991 Integer(kind = i4), Intent (In) :: NORD
992 ! __________________________________________________________
993 Integer(kind = i4), Dimension (NORD) :: XWRKT
994 Integer(kind = i4) :: XWRK, XWRK1
995 !
996 !
997 Integer(kind = i4) :: ICRS, IDCR, ILOW, NDON
998 !
999 xwrkt(1) = xdont(1)
1000 Do icrs = 2, nord
1001 xwrk = xdont(icrs)
1002 Do idcr = icrs - 1, 1, - 1
1003 If (xwrk >= xwrkt(idcr)) Exit
1004 xwrkt(idcr + 1) = xwrkt(idcr)
1005 End Do
1006 xwrkt(idcr + 1) = xwrk
1007 End Do
1008 !
1009 ndon = SIZE (xdont)
1010 xwrk1 = xwrkt(nord)
1011 ilow = 2 * nord - ndon
1012 Do icrs = nord + 1, ndon
1013 If (xdont(icrs) < xwrk1) Then
1014 xwrk = xdont(icrs)
1015 Do idcr = nord - 1, max(1, ilow), - 1
1016 If (xwrk >= xwrkt(idcr)) Exit
1017 xwrkt(idcr + 1) = xwrkt(idcr)
1018 End Do
1019 xwrkt(idcr + 1) = xwrk
1020 xwrk1 = xwrkt(nord)
1021 End If
1022 ilow = ilow + 1
1023 End Do
1024 fndnth = xwrk1
1025
1026 !
1027 End Function i_fndnth
1028
1029 Subroutine d_indmed (XDONT, INDM)
1030 ! Returns index of median value of XDONT.
1031 ! __________________________________________________________
1032 real(kind = dp), Dimension (:), Intent (In) :: xdont
1033 Integer(kind = i4), Intent (Out) :: INDM
1034 ! __________________________________________________________
1035 Integer(kind = i4) :: IDON
1036 !
1037 Allocate (idont(SIZE(xdont)))
1038 Do idon = 1, SIZE(xdont)
1039 idont(idon) = idon
1040 End Do
1041 !
1042 Call d_med (xdont, idont, indm)
1043 !
1044 Deallocate (idont)
1045 End Subroutine d_indmed
1046
1047 Recursive Subroutine d_med (XDATT, IDATT, ires_med)
1048 ! Finds the index of the median of XDONT using the recursive procedure
1049 ! described in Knuth, The Art of Computer Programming,
1050 ! vol. 3, 5.3.3 - This procedure is linear in time, and
1051 ! does not require to be able to interpolate in the
1052 ! set as the one used in INDNTH. It also has better worst
1053 ! case behavior than INDNTH, but is about 30% slower in
1054 ! average for random uniformly distributed values.
1055 ! __________________________________________________________
1056 real(kind = dp), Dimension (:), Intent (In) :: xdatt
1057 Integer(kind = i4), Dimension (:), Intent (In) :: IDATT
1058 Integer(kind = i4), Intent (Out) :: ires_med
1059 ! __________________________________________________________
1060 !
1061 real(kind = dp), Parameter :: xhuge = huge(xdatt)
1062 real(kind = dp) :: xwrk, xwrk1, xmed7, xmax, xmin
1063 !
1064 Integer(kind = i4), Dimension (7 * (((Size (IDATT) + 6) / 7 + 6) / 7)) :: ISTRT, IENDT, IMEDT
1065 Integer(kind = i4), Dimension (7 * ((Size(IDATT) + 6) / 7)) :: IWRKT
1066 Integer(kind = i4) :: NTRI, NMED, NORD, NEQU, NLEQ, IMED, IDON, IDON1
1067 Integer(kind = i4) :: IDEB, ITMP, IDCR, ICRS, ICRS1, ICRS2, IMAX, IMIN
1068 Integer(kind = i4) :: IWRK, IWRK1, IMED1, IMED7, NDAT
1069 !
1070 ndat = Size (idatt)
1071 nmed = (ndat + 1) / 2
1072 iwrkt = idatt
1073 !
1074 ! If the number of values is small, then use insertion sort
1075 !
1076 If (ndat < 35) Then
1077 !
1078 ! Bring minimum to first location to save test in decreasing loop
1079 !
1080 idcr = ndat
1081 If (xdatt(iwrkt(1)) < xdatt(iwrkt(idcr))) Then
1082 iwrk = iwrkt(1)
1083 Else
1084 iwrk = iwrkt(idcr)
1085 iwrkt(idcr) = iwrkt(1)
1086 end if
1087 xwrk = xdatt(iwrk)
1088 Do itmp = 1, ndat - 2
1089 idcr = idcr - 1
1090 iwrk1 = iwrkt(idcr)
1091 xwrk1 = xdatt(iwrk1)
1092 If (xwrk1 < xwrk) Then
1093 iwrkt(idcr) = iwrk
1094 xwrk = xwrk1
1095 iwrk = iwrk1
1096 end if
1097 End Do
1098 iwrkt(1) = iwrk
1099 !
1100 ! Sort the first half, until we have NMED sorted values
1101 !
1102 Do icrs = 3, nmed
1103 xwrk = xdatt(iwrkt(icrs))
1104 iwrk = iwrkt(icrs)
1105 idcr = icrs - 1
1106 Do
1107 If (xwrk >= xdatt(iwrkt(idcr))) Exit
1108 iwrkt(idcr + 1) = iwrkt(idcr)
1109 idcr = idcr - 1
1110 End Do
1111 iwrkt(idcr + 1) = iwrk
1112 End Do
1113 !
1114 ! Insert any value less than the current median in the first half
1115 !
1116 xwrk1 = xdatt(iwrkt(nmed))
1117 Do icrs = nmed + 1, ndat
1118 xwrk = xdatt(iwrkt(icrs))
1119 iwrk = iwrkt(icrs)
1120 If (xwrk < xwrk1) Then
1121 idcr = nmed - 1
1122 Do
1123 If (xwrk >= xdatt(iwrkt(idcr))) Exit
1124 iwrkt(idcr + 1) = iwrkt(idcr)
1125 idcr = idcr - 1
1126 End Do
1127 iwrkt(idcr + 1) = iwrk
1128 xwrk1 = xdatt(iwrkt(nmed))
1129 End If
1130 End Do
1131 ires_med = iwrkt(nmed)
1132 Return
1133 End If
1134 !
1135 ! Make sorted subsets of 7 elements
1136 ! This is done by a variant of insertion sort where a first
1137 ! pass is used to bring the smallest element to the first position
1138 ! decreasing disorder at the same time, so that we may remove
1139 ! remove the loop test in the insertion loop.
1140 !
1141 imax = 1
1142 imin = 1
1143 xmax = xdatt(iwrkt(imax))
1144 xmin = xdatt(iwrkt(imin))
1145 DO ideb = 1, ndat - 6, 7
1146 idcr = ideb + 6
1147 If (xdatt(iwrkt(ideb)) < xdatt(iwrkt(idcr))) Then
1148 iwrk = iwrkt(ideb)
1149 Else
1150 iwrk = iwrkt(idcr)
1151 iwrkt(idcr) = iwrkt(ideb)
1152 end if
1153 xwrk = xdatt(iwrk)
1154 Do itmp = 1, 5
1155 idcr = idcr - 1
1156 iwrk1 = iwrkt(idcr)
1157 xwrk1 = xdatt(iwrk1)
1158 If (xwrk1 < xwrk) Then
1159 iwrkt(idcr) = iwrk
1160 iwrk = iwrk1
1161 xwrk = xwrk1
1162 end if
1163 End Do
1164 iwrkt(ideb) = iwrk
1165 If (xwrk < xmin) Then
1166 imin = iwrk
1167 xmin = xwrk
1168 End If
1169 Do icrs = ideb + 1, ideb + 5
1170 iwrk = iwrkt(icrs + 1)
1171 xwrk = xdatt(iwrk)
1172 idon = iwrkt(icrs)
1173 If (xwrk < xdatt(idon)) Then
1174 iwrkt(icrs + 1) = idon
1175 idcr = icrs
1176 iwrk1 = iwrkt(idcr - 1)
1177 xwrk1 = xdatt(iwrk1)
1178 Do
1179 If (xwrk >= xwrk1) Exit
1180 iwrkt(idcr) = iwrk1
1181 idcr = idcr - 1
1182 iwrk1 = iwrkt(idcr - 1)
1183 xwrk1 = xdatt(iwrk1)
1184 End Do
1185 iwrkt(idcr) = iwrk
1186 end if
1187 End Do
1188 If (xwrk > xmax) Then
1189 imax = iwrk
1190 xmax = xwrk
1191 End If
1192 End Do
1193 !
1194 ! Add-up alternatively MAX and MIN values to make the number of data
1195 ! an exact multiple of 7.
1196 !
1197 ideb = 7 * (ndat / 7)
1198 ntri = ndat
1199 If (ideb < ndat) Then
1200 !
1201 Do icrs = ideb + 1, ndat
1202 xwrk1 = xdatt(iwrkt(icrs))
1203 IF (xwrk1 > xmax) Then
1204 imax = iwrkt(icrs)
1205 xmax = xwrk1
1206 End If
1207 IF (xwrk1 < xmin) Then
1208 imin = iwrkt(icrs)
1209 xmin = xwrk1
1210 End If
1211 End Do
1212 iwrk1 = imax
1213 Do icrs = ndat + 1, ideb + 7
1214 iwrkt(icrs) = iwrk1
1215 If (iwrk1 == imax) Then
1216 iwrk1 = imin
1217 Else
1218 nmed = nmed + 1
1219 iwrk1 = imax
1220 End If
1221 End Do
1222 !
1223 Do icrs = ideb + 2, ideb + 7
1224 iwrk = iwrkt(icrs)
1225 xwrk = xdatt(iwrk)
1226 Do idcr = icrs - 1, ideb + 1, - 1
1227 If (xwrk >= xdatt(iwrkt(idcr))) Exit
1228 iwrkt(idcr + 1) = iwrkt(idcr)
1229 End Do
1230 iwrkt(idcr + 1) = iwrk
1231 End Do
1232 !
1233 ntri = ideb + 7
1234 End If
1235 !
1236 ! Make the set of the indices of median values of each sorted subset
1237 !
1238 idon1 = 0
1239 Do idon = 1, ntri, 7
1240 idon1 = idon1 + 1
1241 imedt(idon1) = iwrkt(idon + 3)
1242 End Do
1243 !
1244 ! Find XMED7, the median of the medians
1245 !
1246 Call d_med (xdatt, imedt(1 : idon1), imed7)
1247 xmed7 = xdatt(imed7)
1248 !
1249 ! Count how many values are not higher than (and how many equal to) XMED7
1250 ! This number is at least 4 * 1/2 * (N/7) : 4 values in each of the
1251 ! subsets where the median is lower than the median of medians. For similar
1252 ! reasons, we also have at least 2N/7 values not lower than XMED7. At the
1253 ! same time, we find in each subset the index of the last value < XMED7,
1254 ! and that of the first > XMED7. These indices will be used to restrict the
1255 ! search for the median as the Kth element in the subset (> or <) where
1256 ! we know it to be.
1257 !
1258 idon1 = 1
1259 nleq = 0
1260 nequ = 0
1261 Do idon = 1, ntri, 7
1262 imed = idon + 3
1263 If (xdatt(iwrkt(imed)) > xmed7) Then
1264 imed = imed - 2
1265 If (xdatt(iwrkt(imed)) > xmed7) Then
1266 imed = imed - 1
1267 Else If (xdatt(iwrkt(imed)) < xmed7) Then
1268 imed = imed + 1
1269 end if
1270 Else If (xdatt(iwrkt(imed)) < xmed7) Then
1271 imed = imed + 2
1272 If (xdatt(iwrkt(imed)) > xmed7) Then
1273 imed = imed - 1
1274 Else If (xdatt(iwrkt(imed)) < xmed7) Then
1275 imed = imed + 1
1276 end if
1277 end if
1278 If (xdatt(iwrkt(imed)) > xmed7) Then
1279 nleq = nleq + imed - idon
1280 iendt(idon1) = imed - 1
1281 istrt(idon1) = imed
1282 Else If (xdatt(iwrkt(imed)) < xmed7) Then
1283 nleq = nleq + imed - idon + 1
1284 iendt(idon1) = imed
1285 istrt(idon1) = imed + 1
1286 Else ! If (XDATT (IWRKT (IMED)) == XMED7)
1287 nleq = nleq + imed - idon + 1
1288 nequ = nequ + 1
1289 iendt(idon1) = imed - 1
1290 Do imed1 = imed - 1, idon, -1
1291 If (eq(xdatt(iwrkt(imed1)), xmed7)) Then
1292 nequ = nequ + 1
1293 iendt(idon1) = imed1 - 1
1294 Else
1295 Exit
1296 End If
1297 End Do
1298 istrt(idon1) = imed + 1
1299 Do imed1 = imed + 1, idon + 6
1300 If (eq(xdatt(iwrkt(imed1)), xmed7)) Then
1301 nequ = nequ + 1
1302 nleq = nleq + 1
1303 istrt(idon1) = imed1 + 1
1304 Else
1305 Exit
1306 End If
1307 End Do
1308 end if
1309 idon1 = idon1 + 1
1310 End Do
1311 !
1312 ! Carry out a partial insertion sort to find the Kth smallest of the
1313 ! large values, or the Kth largest of the small values, according to
1314 ! what is needed.
1315 !
1316 !
1317 If (nleq - nequ + 1 <= nmed) Then
1318 If (nleq < nmed) Then ! Not enough low values
1319 iwrk1 = imax
1320 xwrk1 = xdatt(iwrk1)
1321 nord = nmed - nleq
1322 idon1 = 0
1323 icrs1 = 1
1324 icrs2 = 0
1325 idcr = 0
1326 Do idon = 1, ntri, 7
1327 idon1 = idon1 + 1
1328 If (icrs2 < nord) Then
1329 Do icrs = istrt(idon1), idon + 6
1330 If (xdatt(iwrkt(icrs)) < xwrk1) Then
1331 iwrk = iwrkt(icrs)
1332 xwrk = xdatt(iwrk)
1333 Do idcr = icrs1 - 1, 1, - 1
1334 If (xwrk >= xdatt(iwrkt(idcr))) Exit
1335 iwrkt(idcr + 1) = iwrkt(idcr)
1336 End Do
1337 iwrkt(idcr + 1) = iwrk
1338 iwrk1 = iwrkt(icrs1)
1339 xwrk1 = xdatt(iwrk1)
1340 Else
1341 If (icrs2 < nord) Then
1342 iwrkt(icrs1) = iwrkt(icrs)
1343 iwrk1 = iwrkt(icrs1)
1344 xwrk1 = xdatt(iwrk1)
1345 end if
1346 End If
1347 icrs1 = min(nord, icrs1 + 1)
1348 icrs2 = min(nord, icrs2 + 1)
1349 End Do
1350 Else
1351 Do icrs = istrt(idon1), idon + 6
1352 If (xdatt(iwrkt(icrs)) >= xwrk1) Exit
1353 iwrk = iwrkt(icrs)
1354 xwrk = xdatt(iwrk)
1355 Do idcr = icrs1 - 1, 1, - 1
1356 If (xwrk >= xdatt(iwrkt(idcr))) Exit
1357 iwrkt(idcr + 1) = iwrkt(idcr)
1358 End Do
1359 iwrkt(idcr + 1) = iwrk
1360 iwrk1 = iwrkt(icrs1)
1361 xwrk1 = xdatt(iwrk1)
1362 End Do
1363 End If
1364 End Do
1365 ires_med = iwrk1
1366 Return
1367 Else
1368 ires_med = imed7
1369 Return
1370 End If
1371 Else ! If (NLEQ > NMED)
1372 ! Not enough high values
1373 xwrk1 = -xhuge
1374 nord = nleq - nequ - nmed + 1
1375 idon1 = 0
1376 icrs1 = 1
1377 icrs2 = 0
1378 Do idon = 1, ntri, 7
1379 idon1 = idon1 + 1
1380 If (icrs2 < nord) Then
1381 !
1382 Do icrs = idon, iendt(idon1)
1383 If (xdatt(iwrkt(icrs)) > xwrk1) Then
1384 iwrk = iwrkt(icrs)
1385 xwrk = xdatt(iwrk)
1386 idcr = icrs1 - 1
1387 Do idcr = icrs1 - 1, 1, - 1
1388 If (xwrk <= xdatt(iwrkt(idcr))) Exit
1389 iwrkt(idcr + 1) = iwrkt(idcr)
1390 End Do
1391 iwrkt(idcr + 1) = iwrk
1392 iwrk1 = iwrkt(icrs1)
1393 xwrk1 = xdatt(iwrk1)
1394 Else
1395 If (icrs2 < nord) Then
1396 iwrkt(icrs1) = iwrkt(icrs)
1397 iwrk1 = iwrkt(icrs1)
1398 xwrk1 = xdatt(iwrk1)
1399 End If
1400 End If
1401 icrs1 = min(nord, icrs1 + 1)
1402 icrs2 = min(nord, icrs2 + 1)
1403 End Do
1404 Else
1405 Do icrs = iendt(idon1), idon, -1
1406 If (xdatt(iwrkt(icrs)) <= xwrk1) Exit
1407 iwrk = iwrkt(icrs)
1408 xwrk = xdatt(iwrk)
1409 idcr = icrs1 - 1
1410 Do idcr = icrs1 - 1, 1, - 1
1411 If (xwrk <= xdatt(iwrkt(idcr))) Exit
1412 iwrkt(idcr + 1) = iwrkt(idcr)
1413 End Do
1414 iwrkt(idcr + 1) = iwrk
1415 iwrk1 = iwrkt(icrs1)
1416 xwrk1 = xdatt(iwrk1)
1417 End Do
1418 end if
1419 End Do
1420 !
1421 ires_med = iwrk1
1422 Return
1423 End If
1424 !
1425 END Subroutine d_med
1426 !
1427 Subroutine r_indmed (XDONT, INDM)
1428 ! Returns index of median value of XDONT.
1429 ! __________________________________________________________
1430 Real(kind = sp), Dimension (:), Intent (In) :: xdont
1431 Integer(kind = i4), Intent (Out) :: INDM
1432 ! __________________________________________________________
1433 Integer(kind = i4) :: IDON
1434 !
1435 Allocate (idont(SIZE(xdont)))
1436 Do idon = 1, SIZE(xdont)
1437 idont(idon) = idon
1438 End Do
1439 !
1440 Call r_med (xdont, idont, indm)
1441 !
1442 Deallocate (idont)
1443 End Subroutine r_indmed
1444
1445 Recursive Subroutine r_med (XDATT, IDATT, ires_med)
1446 ! Finds the index of the median of XDONT using the recursive procedure
1447 ! described in Knuth, The Art of Computer Programming,
1448 ! vol. 3, 5.3.3 - This procedure is linear in time, and
1449 ! does not require to be able to interpolate in the
1450 ! set as the one used in INDNTH. It also has better worst
1451 ! case behavior than INDNTH, but is about 30% slower in
1452 ! average for random uniformly distributed values.
1453 ! __________________________________________________________
1454 Real(kind = sp), Dimension (:), Intent (In) :: xdatt
1455 Integer(kind = i4), Dimension (:), Intent (In) :: IDATT
1456 Integer(kind = i4), Intent (Out) :: ires_med
1457 ! __________________________________________________________
1458 !
1459 Real(kind = sp), Parameter :: xhuge = huge(xdatt)
1460 Real(kind = sp) :: xwrk, xwrk1, xmed7, xmax, xmin
1461 !
1462 Integer(kind = i4), Dimension (7 * (((Size (IDATT) + 6) / 7 + 6) / 7)) :: ISTRT, IENDT, IMEDT
1463 Integer(kind = i4), Dimension (7 * ((Size(IDATT) + 6) / 7)) :: IWRKT
1464 Integer(kind = i4) :: NTRI, NMED, NORD, NEQU, NLEQ, IMED, IDON, IDON1
1465 Integer(kind = i4) :: IDEB, ITMP, IDCR, ICRS, ICRS1, ICRS2, IMAX, IMIN
1466 Integer(kind = i4) :: IWRK, IWRK1, IMED1, IMED7, NDAT
1467 !
1468 ndat = Size (idatt)
1469 nmed = (ndat + 1) / 2
1470 iwrkt = idatt
1471 !
1472 ! If the number of values is small, then use insertion sort
1473 !
1474 If (ndat < 35) Then
1475 !
1476 ! Bring minimum to first location to save test in decreasing loop
1477 !
1478 idcr = ndat
1479 If (xdatt(iwrkt(1)) < xdatt(iwrkt(idcr))) Then
1480 iwrk = iwrkt(1)
1481 Else
1482 iwrk = iwrkt(idcr)
1483 iwrkt(idcr) = iwrkt(1)
1484 end if
1485 xwrk = xdatt(iwrk)
1486 Do itmp = 1, ndat - 2
1487 idcr = idcr - 1
1488 iwrk1 = iwrkt(idcr)
1489 xwrk1 = xdatt(iwrk1)
1490 If (xwrk1 < xwrk) Then
1491 iwrkt(idcr) = iwrk
1492 xwrk = xwrk1
1493 iwrk = iwrk1
1494 end if
1495 End Do
1496 iwrkt(1) = iwrk
1497 !
1498 ! Sort the first half, until we have NMED sorted values
1499 !
1500 Do icrs = 3, nmed
1501 xwrk = xdatt(iwrkt(icrs))
1502 iwrk = iwrkt(icrs)
1503 idcr = icrs - 1
1504 Do
1505 If (xwrk >= xdatt(iwrkt(idcr))) Exit
1506 iwrkt(idcr + 1) = iwrkt(idcr)
1507 idcr = idcr - 1
1508 End Do
1509 iwrkt(idcr + 1) = iwrk
1510 End Do
1511 !
1512 ! Insert any value less than the current median in the first half
1513 !
1514 xwrk1 = xdatt(iwrkt(nmed))
1515 Do icrs = nmed + 1, ndat
1516 xwrk = xdatt(iwrkt(icrs))
1517 iwrk = iwrkt(icrs)
1518 If (xwrk < xwrk1) Then
1519 idcr = nmed - 1
1520 Do
1521 If (xwrk >= xdatt(iwrkt(idcr))) Exit
1522 iwrkt(idcr + 1) = iwrkt(idcr)
1523 idcr = idcr - 1
1524 End Do
1525 iwrkt(idcr + 1) = iwrk
1526 xwrk1 = xdatt(iwrkt(nmed))
1527 End If
1528 End Do
1529 ires_med = iwrkt(nmed)
1530 Return
1531 End If
1532 !
1533 ! Make sorted subsets of 7 elements
1534 ! This is done by a variant of insertion sort where a first
1535 ! pass is used to bring the smallest element to the first position
1536 ! decreasing disorder at the same time, so that we may remove
1537 ! remove the loop test in the insertion loop.
1538 !
1539 imax = 1
1540 imin = 1
1541 xmax = xdatt(iwrkt(imax))
1542 xmin = xdatt(iwrkt(imin))
1543 DO ideb = 1, ndat - 6, 7
1544 idcr = ideb + 6
1545 If (xdatt(iwrkt(ideb)) < xdatt(iwrkt(idcr))) Then
1546 iwrk = iwrkt(ideb)
1547 Else
1548 iwrk = iwrkt(idcr)
1549 iwrkt(idcr) = iwrkt(ideb)
1550 end if
1551 xwrk = xdatt(iwrk)
1552 Do itmp = 1, 5
1553 idcr = idcr - 1
1554 iwrk1 = iwrkt(idcr)
1555 xwrk1 = xdatt(iwrk1)
1556 If (xwrk1 < xwrk) Then
1557 iwrkt(idcr) = iwrk
1558 iwrk = iwrk1
1559 xwrk = xwrk1
1560 end if
1561 End Do
1562 iwrkt(ideb) = iwrk
1563 If (xwrk < xmin) Then
1564 imin = iwrk
1565 xmin = xwrk
1566 End If
1567 Do icrs = ideb + 1, ideb + 5
1568 iwrk = iwrkt(icrs + 1)
1569 xwrk = xdatt(iwrk)
1570 idon = iwrkt(icrs)
1571 If (xwrk < xdatt(idon)) Then
1572 iwrkt(icrs + 1) = idon
1573 idcr = icrs
1574 iwrk1 = iwrkt(idcr - 1)
1575 xwrk1 = xdatt(iwrk1)
1576 Do
1577 If (xwrk >= xwrk1) Exit
1578 iwrkt(idcr) = iwrk1
1579 idcr = idcr - 1
1580 iwrk1 = iwrkt(idcr - 1)
1581 xwrk1 = xdatt(iwrk1)
1582 End Do
1583 iwrkt(idcr) = iwrk
1584 end if
1585 End Do
1586 If (xwrk > xmax) Then
1587 imax = iwrk
1588 xmax = xwrk
1589 End If
1590 End Do
1591 !
1592 ! Add-up alternatively MAX and MIN values to make the number of data
1593 ! an exact multiple of 7.
1594 !
1595 ideb = 7 * (ndat / 7)
1596 ntri = ndat
1597 If (ideb < ndat) Then
1598 !
1599 Do icrs = ideb + 1, ndat
1600 xwrk1 = xdatt(iwrkt(icrs))
1601 IF (xwrk1 > xmax) Then
1602 imax = iwrkt(icrs)
1603 xmax = xwrk1
1604 End If
1605 IF (xwrk1 < xmin) Then
1606 imin = iwrkt(icrs)
1607 xmin = xwrk1
1608 End If
1609 End Do
1610 iwrk1 = imax
1611 Do icrs = ndat + 1, ideb + 7
1612 iwrkt(icrs) = iwrk1
1613 If (iwrk1 == imax) Then
1614 iwrk1 = imin
1615 Else
1616 nmed = nmed + 1
1617 iwrk1 = imax
1618 End If
1619 End Do
1620 !
1621 Do icrs = ideb + 2, ideb + 7
1622 iwrk = iwrkt(icrs)
1623 xwrk = xdatt(iwrk)
1624 Do idcr = icrs - 1, ideb + 1, - 1
1625 If (xwrk >= xdatt(iwrkt(idcr))) Exit
1626 iwrkt(idcr + 1) = iwrkt(idcr)
1627 End Do
1628 iwrkt(idcr + 1) = iwrk
1629 End Do
1630 !
1631 ntri = ideb + 7
1632 End If
1633 !
1634 ! Make the set of the indices of median values of each sorted subset
1635 !
1636 idon1 = 0
1637 Do idon = 1, ntri, 7
1638 idon1 = idon1 + 1
1639 imedt(idon1) = iwrkt(idon + 3)
1640 End Do
1641 !
1642 ! Find XMED7, the median of the medians
1643 !
1644 Call r_med (xdatt, imedt(1 : idon1), imed7)
1645 xmed7 = xdatt(imed7)
1646 !
1647 ! Count how many values are not higher than (and how many equal to) XMED7
1648 ! This number is at least 4 * 1/2 * (N/7) : 4 values in each of the
1649 ! subsets where the median is lower than the median of medians. For similar
1650 ! reasons, we also have at least 2N/7 values not lower than XMED7. At the
1651 ! same time, we find in each subset the index of the last value < XMED7,
1652 ! and that of the first > XMED7. These indices will be used to restrict the
1653 ! search for the median as the Kth element in the subset (> or <) where
1654 ! we know it to be.
1655 !
1656 idon1 = 1
1657 nleq = 0
1658 nequ = 0
1659 Do idon = 1, ntri, 7
1660 imed = idon + 3
1661 If (xdatt(iwrkt(imed)) > xmed7) Then
1662 imed = imed - 2
1663 If (xdatt(iwrkt(imed)) > xmed7) Then
1664 imed = imed - 1
1665 Else If (xdatt(iwrkt(imed)) < xmed7) Then
1666 imed = imed + 1
1667 end if
1668 Else If (xdatt(iwrkt(imed)) < xmed7) Then
1669 imed = imed + 2
1670 If (xdatt(iwrkt(imed)) > xmed7) Then
1671 imed = imed - 1
1672 Else If (xdatt(iwrkt(imed)) < xmed7) Then
1673 imed = imed + 1
1674 end if
1675 end if
1676 If (xdatt(iwrkt(imed)) > xmed7) Then
1677 nleq = nleq + imed - idon
1678 iendt(idon1) = imed - 1
1679 istrt(idon1) = imed
1680 Else If (xdatt(iwrkt(imed)) < xmed7) Then
1681 nleq = nleq + imed - idon + 1
1682 iendt(idon1) = imed
1683 istrt(idon1) = imed + 1
1684 Else ! If (XDATT (IWRKT (IMED)) == XMED7)
1685 nleq = nleq + imed - idon + 1
1686 nequ = nequ + 1
1687 iendt(idon1) = imed - 1
1688 Do imed1 = imed - 1, idon, -1
1689 If (eq(xdatt(iwrkt(imed1)), xmed7)) Then
1690 nequ = nequ + 1
1691 iendt(idon1) = imed1 - 1
1692 Else
1693 Exit
1694 End If
1695 End Do
1696 istrt(idon1) = imed + 1
1697 Do imed1 = imed + 1, idon + 6
1698 If (eq(xdatt(iwrkt(imed1)), xmed7)) Then
1699 nequ = nequ + 1
1700 nleq = nleq + 1
1701 istrt(idon1) = imed1 + 1
1702 Else
1703 Exit
1704 End If
1705 End Do
1706 end if
1707 idon1 = idon1 + 1
1708 End Do
1709 !
1710 ! Carry out a partial insertion sort to find the Kth smallest of the
1711 ! large values, or the Kth largest of the small values, according to
1712 ! what is needed.
1713 !
1714 !
1715 If (nleq - nequ + 1 <= nmed) Then
1716 If (nleq < nmed) Then ! Not enough low values
1717 iwrk1 = imax
1718 xwrk1 = xdatt(iwrk1)
1719 nord = nmed - nleq
1720 idon1 = 0
1721 icrs1 = 1
1722 icrs2 = 0
1723 idcr = 0
1724 Do idon = 1, ntri, 7
1725 idon1 = idon1 + 1
1726 If (icrs2 < nord) Then
1727 Do icrs = istrt(idon1), idon + 6
1728 If (xdatt(iwrkt(icrs)) < xwrk1) Then
1729 iwrk = iwrkt(icrs)
1730 xwrk = xdatt(iwrk)
1731 Do idcr = icrs1 - 1, 1, - 1
1732 If (xwrk >= xdatt(iwrkt(idcr))) Exit
1733 iwrkt(idcr + 1) = iwrkt(idcr)
1734 End Do
1735 iwrkt(idcr + 1) = iwrk
1736 iwrk1 = iwrkt(icrs1)
1737 xwrk1 = xdatt(iwrk1)
1738 Else
1739 If (icrs2 < nord) Then
1740 iwrkt(icrs1) = iwrkt(icrs)
1741 iwrk1 = iwrkt(icrs1)
1742 xwrk1 = xdatt(iwrk1)
1743 end if
1744 End If
1745 icrs1 = min(nord, icrs1 + 1)
1746 icrs2 = min(nord, icrs2 + 1)
1747 End Do
1748 Else
1749 Do icrs = istrt(idon1), idon + 6
1750 If (xdatt(iwrkt(icrs)) >= xwrk1) Exit
1751 iwrk = iwrkt(icrs)
1752 xwrk = xdatt(iwrk)
1753 Do idcr = icrs1 - 1, 1, - 1
1754 If (xwrk >= xdatt(iwrkt(idcr))) Exit
1755 iwrkt(idcr + 1) = iwrkt(idcr)
1756 End Do
1757 iwrkt(idcr + 1) = iwrk
1758 iwrk1 = iwrkt(icrs1)
1759 xwrk1 = xdatt(iwrk1)
1760 End Do
1761 End If
1762 End Do
1763 ires_med = iwrk1
1764 Return
1765 Else
1766 ires_med = imed7
1767 Return
1768 End If
1769 Else ! If (NLEQ > NMED)
1770 ! Not enough high values
1771 xwrk1 = -xhuge
1772 nord = nleq - nequ - nmed + 1
1773 idon1 = 0
1774 icrs1 = 1
1775 icrs2 = 0
1776 Do idon = 1, ntri, 7
1777 idon1 = idon1 + 1
1778 If (icrs2 < nord) Then
1779 !
1780 Do icrs = idon, iendt(idon1)
1781 If (xdatt(iwrkt(icrs)) > xwrk1) Then
1782 iwrk = iwrkt(icrs)
1783 xwrk = xdatt(iwrk)
1784 idcr = icrs1 - 1
1785 Do idcr = icrs1 - 1, 1, - 1
1786 If (xwrk <= xdatt(iwrkt(idcr))) Exit
1787 iwrkt(idcr + 1) = iwrkt(idcr)
1788 End Do
1789 iwrkt(idcr + 1) = iwrk
1790 iwrk1 = iwrkt(icrs1)
1791 xwrk1 = xdatt(iwrk1)
1792 Else
1793 If (icrs2 < nord) Then
1794 iwrkt(icrs1) = iwrkt(icrs)
1795 iwrk1 = iwrkt(icrs1)
1796 xwrk1 = xdatt(iwrk1)
1797 End If
1798 End If
1799 icrs1 = min(nord, icrs1 + 1)
1800 icrs2 = min(nord, icrs2 + 1)
1801 End Do
1802 Else
1803 Do icrs = iendt(idon1), idon, -1
1804 If (xdatt(iwrkt(icrs)) <= xwrk1) Exit
1805 iwrk = iwrkt(icrs)
1806 xwrk = xdatt(iwrk)
1807 idcr = icrs1 - 1
1808 Do idcr = icrs1 - 1, 1, - 1
1809 If (xwrk <= xdatt(iwrkt(idcr))) Exit
1810 iwrkt(idcr + 1) = iwrkt(idcr)
1811 End Do
1812 iwrkt(idcr + 1) = iwrk
1813 iwrk1 = iwrkt(icrs1)
1814 xwrk1 = xdatt(iwrk1)
1815 End Do
1816 end if
1817 End Do
1818 !
1819 ires_med = iwrk1
1820 Return
1821 End If
1822 !
1823 END Subroutine r_med
1824
1825 Subroutine i_indmed (XDONT, INDM)
1826 ! Returns index of median value of XDONT.
1827 ! __________________________________________________________
1828 Integer(kind = i4), Dimension (:), Intent (In) :: XDONT
1829 Integer(kind = i4), Intent (Out) :: INDM
1830 ! __________________________________________________________
1831 Integer(kind = i4) :: IDON
1832 !
1833 Allocate (idont(SIZE(xdont)))
1834 Do idon = 1, SIZE(xdont)
1835 idont(idon) = idon
1836 End Do
1837 !
1838 Call i_med(xdont, idont, indm)
1839 !
1840 Deallocate (idont)
1841 End Subroutine i_indmed
1842
1843 Recursive Subroutine i_med (XDATT, IDATT, ires_med)
1844 ! Finds the index of the median of XDONT using the recursive procedure
1845 ! described in Knuth, The Art of Computer Programming,
1846 ! vol. 3, 5.3.3 - This procedure is linear in time, and
1847 ! does not require to be able to interpolate in the
1848 ! set as the one used in INDNTH. It also has better worst
1849 ! case behavior than INDNTH, but is about 30% slower in
1850 ! average for random uniformly distributed values.
1851 ! __________________________________________________________
1852 Integer(kind = i4), Dimension (:), Intent (In) :: XDATT
1853 Integer(kind = i4), Dimension (:), Intent (In) :: IDATT
1854 Integer(kind = i4), Intent (Out) :: ires_med
1855 ! __________________________________________________________
1856 !
1857 Integer(kind = i4), Parameter :: XHUGE = huge (xdatt)
1858 Integer(kind = i4) :: XWRK, XWRK1, XMED7, XMAX, XMIN
1859 !
1860 Integer(kind = i4), Dimension (7 * (((Size (IDATT) + 6) / 7 + 6) / 7)) :: ISTRT, IENDT, IMEDT
1861 Integer(kind = i4), Dimension (7 * ((Size(IDATT) + 6) / 7)) :: IWRKT
1862 Integer(kind = i4) :: NTRI, NMED, NORD, NEQU, NLEQ, IMED, IDON, IDON1
1863 Integer(kind = i4) :: IDEB, ITMP, IDCR, ICRS, ICRS1, ICRS2, IMAX, IMIN
1864 Integer(kind = i4) :: IWRK, IWRK1, IMED1, IMED7, NDAT
1865 !
1866 ndat = Size (idatt)
1867 nmed = (ndat + 1) / 2
1868 iwrkt = idatt
1869 !
1870 ! If the number of values is small, then use insertion sort
1871 !
1872 If (ndat < 35) Then
1873 !
1874 ! Bring minimum to first location to save test in decreasing loop
1875 !
1876 idcr = ndat
1877 If (xdatt(iwrkt(1)) < xdatt(iwrkt(idcr))) Then
1878 iwrk = iwrkt(1)
1879 Else
1880 iwrk = iwrkt(idcr)
1881 iwrkt(idcr) = iwrkt(1)
1882 end if
1883 xwrk = xdatt(iwrk)
1884 Do itmp = 1, ndat - 2
1885 idcr = idcr - 1
1886 iwrk1 = iwrkt(idcr)
1887 xwrk1 = xdatt(iwrk1)
1888 If (xwrk1 < xwrk) Then
1889 iwrkt(idcr) = iwrk
1890 xwrk = xwrk1
1891 iwrk = iwrk1
1892 end if
1893 End Do
1894 iwrkt(1) = iwrk
1895 !
1896 ! Sort the first half, until we have NMED sorted values
1897 !
1898 Do icrs = 3, nmed
1899 xwrk = xdatt(iwrkt(icrs))
1900 iwrk = iwrkt(icrs)
1901 idcr = icrs - 1
1902 Do
1903 If (xwrk >= xdatt(iwrkt(idcr))) Exit
1904 iwrkt(idcr + 1) = iwrkt(idcr)
1905 idcr = idcr - 1
1906 End Do
1907 iwrkt(idcr + 1) = iwrk
1908 End Do
1909 !
1910 ! Insert any value less than the current median in the first half
1911 !
1912 xwrk1 = xdatt(iwrkt(nmed))
1913 Do icrs = nmed + 1, ndat
1914 xwrk = xdatt(iwrkt(icrs))
1915 iwrk = iwrkt(icrs)
1916 If (xwrk < xwrk1) Then
1917 idcr = nmed - 1
1918 Do
1919 If (xwrk >= xdatt(iwrkt(idcr))) Exit
1920 iwrkt(idcr + 1) = iwrkt(idcr)
1921 idcr = idcr - 1
1922 End Do
1923 iwrkt(idcr + 1) = iwrk
1924 xwrk1 = xdatt(iwrkt(nmed))
1925 End If
1926 End Do
1927 ires_med = iwrkt(nmed)
1928 Return
1929 End If
1930 !
1931 ! Make sorted subsets of 7 elements
1932 ! This is done by a variant of insertion sort where a first
1933 ! pass is used to bring the smallest element to the first position
1934 ! decreasing disorder at the same time, so that we may remove
1935 ! remove the loop test in the insertion loop.
1936 !
1937 imax = 1
1938 imin = 1
1939 xmax = xdatt(iwrkt(imax))
1940 xmin = xdatt(iwrkt(imin))
1941 DO ideb = 1, ndat - 6, 7
1942 idcr = ideb + 6
1943 If (xdatt(iwrkt(ideb)) < xdatt(iwrkt(idcr))) Then
1944 iwrk = iwrkt(ideb)
1945 Else
1946 iwrk = iwrkt(idcr)
1947 iwrkt(idcr) = iwrkt(ideb)
1948 end if
1949 xwrk = xdatt(iwrk)
1950 Do itmp = 1, 5
1951 idcr = idcr - 1
1952 iwrk1 = iwrkt(idcr)
1953 xwrk1 = xdatt(iwrk1)
1954 If (xwrk1 < xwrk) Then
1955 iwrkt(idcr) = iwrk
1956 iwrk = iwrk1
1957 xwrk = xwrk1
1958 end if
1959 End Do
1960 iwrkt(ideb) = iwrk
1961 If (xwrk < xmin) Then
1962 imin = iwrk
1963 xmin = xwrk
1964 End If
1965 Do icrs = ideb + 1, ideb + 5
1966 iwrk = iwrkt(icrs + 1)
1967 xwrk = xdatt(iwrk)
1968 idon = iwrkt(icrs)
1969 If (xwrk < xdatt(idon)) Then
1970 iwrkt(icrs + 1) = idon
1971 idcr = icrs
1972 iwrk1 = iwrkt(idcr - 1)
1973 xwrk1 = xdatt(iwrk1)
1974 Do
1975 If (xwrk >= xwrk1) Exit
1976 iwrkt(idcr) = iwrk1
1977 idcr = idcr - 1
1978 iwrk1 = iwrkt(idcr - 1)
1979 xwrk1 = xdatt(iwrk1)
1980 End Do
1981 iwrkt(idcr) = iwrk
1982 end if
1983 End Do
1984 If (xwrk > xmax) Then
1985 imax = iwrk
1986 xmax = xwrk
1987 End If
1988 End Do
1989 !
1990 ! Add-up alternatively MAX and MIN values to make the number of data
1991 ! an exact multiple of 7.
1992 !
1993 ideb = 7 * (ndat / 7)
1994 ntri = ndat
1995 If (ideb < ndat) Then
1996 !
1997 Do icrs = ideb + 1, ndat
1998 xwrk1 = xdatt(iwrkt(icrs))
1999 IF (xwrk1 > xmax) Then
2000 imax = iwrkt(icrs)
2001 xmax = xwrk1
2002 End If
2003 IF (xwrk1 < xmin) Then
2004 imin = iwrkt(icrs)
2005 xmin = xwrk1
2006 End If
2007 End Do
2008 iwrk1 = imax
2009 Do icrs = ndat + 1, ideb + 7
2010 iwrkt(icrs) = iwrk1
2011 If (iwrk1 == imax) Then
2012 iwrk1 = imin
2013 Else
2014 nmed = nmed + 1
2015 iwrk1 = imax
2016 End If
2017 End Do
2018 !
2019 Do icrs = ideb + 2, ideb + 7
2020 iwrk = iwrkt(icrs)
2021 xwrk = xdatt(iwrk)
2022 Do idcr = icrs - 1, ideb + 1, - 1
2023 If (xwrk >= xdatt(iwrkt(idcr))) Exit
2024 iwrkt(idcr + 1) = iwrkt(idcr)
2025 End Do
2026 iwrkt(idcr + 1) = iwrk
2027 End Do
2028 !
2029 ntri = ideb + 7
2030 End If
2031 !
2032 ! Make the set of the indices of median values of each sorted subset
2033 !
2034 idon1 = 0
2035 Do idon = 1, ntri, 7
2036 idon1 = idon1 + 1
2037 imedt(idon1) = iwrkt(idon + 3)
2038 End Do
2039 !
2040 ! Find XMED7, the median of the medians
2041 !
2042 Call i_med (xdatt, imedt(1 : idon1), imed7)
2043 xmed7 = xdatt(imed7)
2044 !
2045 ! Count how many values are not higher than (and how many equal to) XMED7
2046 ! This number is at least 4 * 1/2 * (N/7) : 4 values in each of the
2047 ! subsets where the median is lower than the median of medians. For similar
2048 ! reasons, we also have at least 2N/7 values not lower than XMED7. At the
2049 ! same time, we find in each subset the index of the last value < XMED7,
2050 ! and that of the first > XMED7. These indices will be used to restrict the
2051 ! search for the median as the Kth element in the subset (> or <) where
2052 ! we know it to be.
2053 !
2054 idon1 = 1
2055 nleq = 0
2056 nequ = 0
2057 Do idon = 1, ntri, 7
2058 imed = idon + 3
2059 If (xdatt(iwrkt(imed)) > xmed7) Then
2060 imed = imed - 2
2061 If (xdatt(iwrkt(imed)) > xmed7) Then
2062 imed = imed - 1
2063 Else If (xdatt(iwrkt(imed)) < xmed7) Then
2064 imed = imed + 1
2065 end if
2066 Else If (xdatt(iwrkt(imed)) < xmed7) Then
2067 imed = imed + 2
2068 If (xdatt(iwrkt(imed)) > xmed7) Then
2069 imed = imed - 1
2070 Else If (xdatt(iwrkt(imed)) < xmed7) Then
2071 imed = imed + 1
2072 end if
2073 end if
2074 If (xdatt(iwrkt(imed)) > xmed7) Then
2075 nleq = nleq + imed - idon
2076 iendt(idon1) = imed - 1
2077 istrt(idon1) = imed
2078 Else If (xdatt(iwrkt(imed)) < xmed7) Then
2079 nleq = nleq + imed - idon + 1
2080 iendt(idon1) = imed
2081 istrt(idon1) = imed + 1
2082 Else ! If (XDATT (IWRKT (IMED)) == XMED7)
2083 nleq = nleq + imed - idon + 1
2084 nequ = nequ + 1
2085 iendt(idon1) = imed - 1
2086 Do imed1 = imed - 1, idon, -1
2087 If (xdatt(iwrkt(imed1)) == xmed7) Then
2088 nequ = nequ + 1
2089 iendt(idon1) = imed1 - 1
2090 Else
2091 Exit
2092 End If
2093 End Do
2094 istrt(idon1) = imed + 1
2095 Do imed1 = imed + 1, idon + 6
2096 If (xdatt(iwrkt(imed1)) == xmed7) Then
2097 nequ = nequ + 1
2098 nleq = nleq + 1
2099 istrt(idon1) = imed1 + 1
2100 Else
2101 Exit
2102 End If
2103 End Do
2104 end if
2105 idon1 = idon1 + 1
2106 End Do
2107 !
2108 ! Carry out a partial insertion sort to find the Kth smallest of the
2109 ! large values, or the Kth largest of the small values, according to
2110 ! what is needed.
2111 !
2112 !
2113 If (nleq - nequ + 1 <= nmed) Then
2114 If (nleq < nmed) Then ! Not enough low values
2115 iwrk1 = imax
2116 xwrk1 = xdatt(iwrk1)
2117 nord = nmed - nleq
2118 idon1 = 0
2119 icrs1 = 1
2120 icrs2 = 0
2121 idcr = 0
2122 Do idon = 1, ntri, 7
2123 idon1 = idon1 + 1
2124 If (icrs2 < nord) Then
2125 Do icrs = istrt(idon1), idon + 6
2126 If (xdatt(iwrkt(icrs)) < xwrk1) Then
2127 iwrk = iwrkt(icrs)
2128 xwrk = xdatt(iwrk)
2129 Do idcr = icrs1 - 1, 1, - 1
2130 If (xwrk >= xdatt(iwrkt(idcr))) Exit
2131 iwrkt(idcr + 1) = iwrkt(idcr)
2132 End Do
2133 iwrkt(idcr + 1) = iwrk
2134 iwrk1 = iwrkt(icrs1)
2135 xwrk1 = xdatt(iwrk1)
2136 Else
2137 If (icrs2 < nord) Then
2138 iwrkt(icrs1) = iwrkt(icrs)
2139 iwrk1 = iwrkt(icrs1)
2140 xwrk1 = xdatt(iwrk1)
2141 end if
2142 End If
2143 icrs1 = min(nord, icrs1 + 1)
2144 icrs2 = min(nord, icrs2 + 1)
2145 End Do
2146 Else
2147 Do icrs = istrt(idon1), idon + 6
2148 If (xdatt(iwrkt(icrs)) >= xwrk1) Exit
2149 iwrk = iwrkt(icrs)
2150 xwrk = xdatt(iwrk)
2151 Do idcr = icrs1 - 1, 1, - 1
2152 If (xwrk >= xdatt(iwrkt(idcr))) Exit
2153 iwrkt(idcr + 1) = iwrkt(idcr)
2154 End Do
2155 iwrkt(idcr + 1) = iwrk
2156 iwrk1 = iwrkt(icrs1)
2157 xwrk1 = xdatt(iwrk1)
2158 End Do
2159 End If
2160 End Do
2161 ires_med = iwrk1
2162 Return
2163 Else
2164 ires_med = imed7
2165 Return
2166 End If
2167 Else ! If (NLEQ > NMED)
2168 ! Not enough high values
2169 xwrk1 = -xhuge
2170 nord = nleq - nequ - nmed + 1
2171 idon1 = 0
2172 icrs1 = 1
2173 icrs2 = 0
2174 Do idon = 1, ntri, 7
2175 idon1 = idon1 + 1
2176 If (icrs2 < nord) Then
2177 !
2178 Do icrs = idon, iendt(idon1)
2179 If (xdatt(iwrkt(icrs)) > xwrk1) Then
2180 iwrk = iwrkt(icrs)
2181 xwrk = xdatt(iwrk)
2182 idcr = icrs1 - 1
2183 Do idcr = icrs1 - 1, 1, - 1
2184 If (xwrk <= xdatt(iwrkt(idcr))) Exit
2185 iwrkt(idcr + 1) = iwrkt(idcr)
2186 End Do
2187 iwrkt(idcr + 1) = iwrk
2188 iwrk1 = iwrkt(icrs1)
2189 xwrk1 = xdatt(iwrk1)
2190 Else
2191 If (icrs2 < nord) Then
2192 iwrkt(icrs1) = iwrkt(icrs)
2193 iwrk1 = iwrkt(icrs1)
2194 xwrk1 = xdatt(iwrk1)
2195 End If
2196 End If
2197 icrs1 = min(nord, icrs1 + 1)
2198 icrs2 = min(nord, icrs2 + 1)
2199 End Do
2200 Else
2201 Do icrs = iendt(idon1), idon, -1
2202 If (xdatt(iwrkt(icrs)) <= xwrk1) Exit
2203 iwrk = iwrkt(icrs)
2204 xwrk = xdatt(iwrk)
2205 idcr = icrs1 - 1
2206 Do idcr = icrs1 - 1, 1, - 1
2207 If (xwrk <= xdatt(iwrkt(idcr))) Exit
2208 iwrkt(idcr + 1) = iwrkt(idcr)
2209 End Do
2210 iwrkt(idcr + 1) = iwrk
2211 iwrk1 = iwrkt(icrs1)
2212 xwrk1 = xdatt(iwrk1)
2213 End Do
2214 end if
2215 End Do
2216 !
2217 ires_med = iwrk1
2218 Return
2219 End If
2220 !
2221 END Subroutine i_med
2222
2223 Function d_indnth (XDONT, NORD) Result (INDNTH)
2224 ! Return NORDth value of XDONT, i.e fractile of order NORD/SIZE(XDONT).
2225 ! __________________________________________________________
2226 ! This routine uses a pivoting strategy such as the one of
2227 ! finding the median based on the quicksort algorithm, but
2228 ! we skew the pivot choice to try to bring it to NORD as
2229 ! fast as possible. It uses 2 temporary arrays, where it
2230 ! stores the indices of the values smaller than the pivot
2231 ! (ILOWT), and the indices of values larger than the pivot
2232 ! that we might still need later on (IHIGT). It iterates
2233 ! until it can bring the number of values in ILOWT to
2234 ! exactly NORD, and then finds the maximum of this set.
2235 ! Michel Olagnon - Aug. 2000
2236 ! __________________________________________________________
2237 ! __________________________________________________________
2238 real(kind = dp), Dimension (:), Intent (In) :: xdont
2239 Integer(kind = i4) :: INDNTH
2240 Integer(kind = i4), Intent (In) :: NORD
2241 ! __________________________________________________________
2242 real(kind = dp) :: xpiv, xwrk, xwrk1, xmin, xmax
2243 !
2244 Integer(kind = i4), Dimension (NORD) :: IRNGT
2245 Integer(kind = i4), Dimension (SIZE(XDONT)) :: ILOWT, IHIGT
2246 Integer(kind = i4) :: NDON, JHIG, JLOW, IHIG, IWRK, IWRK1, IWRK2, IWRK3
2247 Integer(kind = i4) :: IMIL, IFIN, ICRS, IDCR, ILOW
2248 Integer(kind = i4) :: JLM2, JLM1, JHM2, JHM1, INTH
2249 !
2250 ndon = SIZE (xdont)
2251 inth = nord
2252 !
2253 ! First loop is used to fill-in ILOWT, IHIGT at the same time
2254 !
2255 If (ndon < 2) Then
2256 If (inth == 1) indnth = 1
2257 Return
2258 End If
2259 !
2260 ! One chooses a pivot, best estimate possible to put fractile near
2261 ! mid-point of the set of low values.
2262 !
2263 If (xdont(2) < xdont(1)) Then
2264 ilowt(1) = 2
2265 ihigt(1) = 1
2266 Else
2267 ilowt(1) = 1
2268 ihigt(1) = 2
2269 End If
2270 !
2271 If (ndon < 3) Then
2272 If (inth == 1) indnth = ilowt(1)
2273 If (inth == 2) indnth = ihigt(1)
2274 Return
2275 End If
2276 !
2277 If (xdont(3) < xdont(ihigt(1))) Then
2278 ihigt(2) = ihigt(1)
2279 If (xdont(3) < xdont(ilowt(1))) Then
2280 ihigt(1) = ilowt(1)
2281 ilowt(1) = 3
2282 Else
2283 ihigt(1) = 3
2284 End If
2285 Else
2286 ihigt(2) = 3
2287 End If
2288 !
2289 If (ndon < 4) Then
2290 If (inth == 1) indnth = ilowt(1)
2291 If (inth == 2) indnth = ihigt(1)
2292 If (inth == 3) indnth = ihigt(2)
2293 Return
2294 End If
2295 !
2296 If (xdont(ndon) < xdont(ihigt(1))) Then
2297 ihigt(3) = ihigt(2)
2298 ihigt(2) = ihigt(1)
2299 If (xdont(ndon) < xdont(ilowt(1))) Then
2300 ihigt(1) = ilowt(1)
2301 ilowt(1) = ndon
2302 Else
2303 ihigt(1) = ndon
2304 End If
2305 Else
2306 ihigt(3) = ndon
2307 End If
2308 !
2309 If (ndon < 5) Then
2310 If (inth == 1) indnth = ilowt(1)
2311 If (inth == 2) indnth = ihigt(1)
2312 If (inth == 3) indnth = ihigt(2)
2313 If (inth == 4) indnth = ihigt(3)
2314 Return
2315 End If
2316 !
2317
2318 jlow = 1
2319 jhig = 3
2320 xpiv = xdont(ilowt(1)) + real(2 * inth, dp) / real(ndon + inth, dp) * &
2321 (xdont(ihigt(3)) - xdont(ilowt(1)))
2322 If (xpiv >= xdont(ihigt(1))) Then
2323 xpiv = xdont(ilowt(1)) + real(2 * inth, dp) / real(ndon + inth, dp) * &
2324 (xdont(ihigt(2)) - xdont(ilowt(1)))
2325 If (xpiv >= xdont(ihigt(1))) &
2326 xpiv = xdont(ilowt(1)) + real(2 * inth, dp) / real(ndon + inth, dp) * &
2327 (xdont(ihigt(1)) - xdont(ilowt(1)))
2328 End If
2329 !
2330 ! One puts values > pivot in the end and those <= pivot
2331 ! at the beginning. This is split in 2 cases, so that
2332 ! we can skip the loop test a number of times.
2333 ! As we are also filling in the work arrays at the same time
2334 ! we stop filling in the IHIGT array as soon as we have more
2335 ! than enough values in ILOWT.
2336 !
2337 !
2338 If (xdont(ndon) > xpiv) Then
2339 icrs = 3
2340 Do
2341 icrs = icrs + 1
2342 If (xdont(icrs) > xpiv) Then
2343 If (icrs >= ndon) Exit
2344 jhig = jhig + 1
2345 ihigt(jhig) = icrs
2346 Else
2347 jlow = jlow + 1
2348 ilowt(jlow) = icrs
2349 If (jlow >= inth) Exit
2350 End If
2351 End Do
2352 !
2353 ! One restricts further processing because it is no use
2354 ! to store more high values
2355 !
2356 If (icrs < ndon - 1) Then
2357 Do
2358 icrs = icrs + 1
2359 If (xdont(icrs) <= xpiv) Then
2360 jlow = jlow + 1
2361 ilowt(jlow) = icrs
2362 Else If (icrs >= ndon) Then
2363 Exit
2364 End If
2365 End Do
2366 End If
2367 !
2368 !
2369 Else
2370 !
2371 ! Same as above, but this is not as easy to optimize, so the
2372 ! DO-loop is kept
2373 !
2374 Do icrs = 4, ndon - 1
2375 If (xdont(icrs) > xpiv) Then
2376 jhig = jhig + 1
2377 ihigt(jhig) = icrs
2378 Else
2379 jlow = jlow + 1
2380 ilowt(jlow) = icrs
2381 If (jlow >= inth) Exit
2382 End If
2383 End Do
2384 !
2385 If (icrs < ndon - 1) Then
2386 Do
2387 icrs = icrs + 1
2388 If (xdont(icrs) <= xpiv) Then
2389 If (icrs >= ndon) Exit
2390 jlow = jlow + 1
2391 ilowt(jlow) = icrs
2392 End If
2393 End Do
2394 End If
2395 End If
2396 !
2397 jlm2 = 0
2398 jlm1 = 0
2399 jhm2 = 0
2400 jhm1 = 0
2401 Do
2402 If (jlm2 == jlow .And. jhm2 == jhig) Then
2403 !
2404 ! We are oscillating. Perturbate by bringing JLOW closer by one
2405 ! to INTH
2406 !
2407 If (inth > jlow) Then
2408 xmin = xdont(ihigt(1))
2409 ihig = 1
2410 Do icrs = 2, jhig
2411 If (xdont(ihigt(icrs)) < xmin) Then
2412 xmin = xdont(ihigt(icrs))
2413 ihig = icrs
2414 End If
2415 End Do
2416 !
2417 jlow = jlow + 1
2418 ilowt(jlow) = ihigt(ihig)
2419 ihigt(ihig) = ihigt(jhig)
2420 jhig = jhig - 1
2421 Else
2422
2423 ilow = ilowt(1)
2424 xmax = xdont(ilow)
2425 Do icrs = 2, jlow
2426 If (xdont(ilowt(icrs)) > xmax) Then
2427 iwrk = ilowt(icrs)
2428 xmax = xdont(iwrk)
2429 ilowt(icrs) = ilow
2430 ilow = iwrk
2431 End If
2432 End Do
2433 jlow = jlow - 1
2434 End If
2435 End If
2436 jlm2 = jlm1
2437 jlm1 = jlow
2438 jhm2 = jhm1
2439 jhm1 = jhig
2440 !
2441 ! We try to bring the number of values in the low values set
2442 ! closer to INTH.
2443 !
2444 Select Case (inth - jlow)
2445 Case (2 :)
2446 !
2447 ! Not enough values in low part, at least 2 are missing
2448 !
2449 inth = inth - jlow
2450 jlow = 0
2451 Select Case (jhig)
2452 !!!!! CASE DEFAULT
2453 !!!!! write (unit=*,fmt=*) "Assertion failed"
2454 !!!!! STOP
2455 !
2456 ! We make a special case when we have so few values in
2457 ! the high values set that it is bad performance to choose a pivot
2458 ! and apply the general algorithm.
2459 !
2460 Case (2)
2461 If (xdont(ihigt(1)) <= xdont(ihigt(2))) Then
2462 jlow = jlow + 1
2463 ilowt(jlow) = ihigt(1)
2464 jlow = jlow + 1
2465 ilowt(jlow) = ihigt(2)
2466 Else
2467 jlow = jlow + 1
2468 ilowt(jlow) = ihigt(2)
2469 jlow = jlow + 1
2470 ilowt(jlow) = ihigt(1)
2471 End If
2472 Exit
2473 !
2474 Case (3)
2475 !
2476 !
2477 iwrk1 = ihigt(1)
2478 iwrk2 = ihigt(2)
2479 iwrk3 = ihigt(3)
2480 If (xdont(iwrk2) < xdont(iwrk1)) Then
2481 ihigt(1) = iwrk2
2482 ihigt(2) = iwrk1
2483 iwrk2 = iwrk1
2484 End If
2485 If (xdont(iwrk2) > xdont(iwrk3)) Then
2486 ihigt(3) = iwrk2
2487 ihigt(2) = iwrk3
2488 iwrk2 = iwrk3
2489 If (xdont(iwrk2) < xdont(ihigt(1))) Then
2490 ihigt(2) = ihigt(1)
2491 ihigt(1) = iwrk2
2492 End If
2493 End If
2494 jhig = 0
2495 Do icrs = jlow + 1, inth
2496 jhig = jhig + 1
2497 ilowt(icrs) = ihigt(jhig)
2498 End Do
2499 jlow = inth
2500 Exit
2501 !
2502 Case (4 :)
2503 !
2504 !
2505 ifin = jhig
2506 !
2507 ! One chooses a pivot from the 2 first values and the last one.
2508 ! This should ensure sufficient renewal between iterations to
2509 ! avoid worst case behavior effects.
2510 !
2511 iwrk1 = ihigt(1)
2512 iwrk2 = ihigt(2)
2513 iwrk3 = ihigt(ifin)
2514 If (xdont(iwrk2) < xdont(iwrk1)) Then
2515 ihigt(1) = iwrk2
2516 ihigt(2) = iwrk1
2517 iwrk2 = iwrk1
2518 End If
2519 If (xdont(iwrk2) > xdont(iwrk3)) Then
2520 ihigt(ifin) = iwrk2
2521 ihigt(2) = iwrk3
2522 iwrk2 = iwrk3
2523 If (xdont(iwrk2) < xdont(ihigt(1))) Then
2524 ihigt(2) = ihigt(1)
2525 ihigt(1) = iwrk2
2526 End If
2527 End If
2528 !
2529 iwrk1 = ihigt(1)
2530 jlow = jlow + 1
2531 ilowt(jlow) = iwrk1
2532 xpiv = xdont(iwrk1) + 0.5 * (xdont(ihigt(ifin)) - xdont(iwrk1))
2533 !
2534 ! One takes values <= pivot to ILOWT
2535 ! Again, 2 parts, one where we take care of the remaining
2536 ! high values because we might still need them, and the
2537 ! other when we know that we will have more than enough
2538 ! low values in the end.
2539 !
2540 jhig = 0
2541 Do icrs = 2, ifin
2542 If (xdont(ihigt(icrs)) <= xpiv) Then
2543 jlow = jlow + 1
2544 ilowt(jlow) = ihigt(icrs)
2545 If (jlow >= inth) Exit
2546 Else
2547 jhig = jhig + 1
2548 ihigt(jhig) = ihigt(icrs)
2549 End If
2550 End Do
2551 !
2552 Do icrs = icrs + 1, ifin
2553 If (xdont(ihigt(icrs)) <= xpiv) Then
2554 jlow = jlow + 1
2555 ilowt(jlow) = ihigt(icrs)
2556 End If
2557 End Do
2558 End Select
2559 !
2560 !
2561 Case (1)
2562 !
2563 ! Only 1 value is missing in low part
2564 !
2565 xmin = xdont(ihigt(1))
2566 ihig = 1
2567 Do icrs = 2, jhig
2568 If (xdont(ihigt(icrs)) < xmin) Then
2569 xmin = xdont(ihigt(icrs))
2570 ihig = icrs
2571 End If
2572 End Do
2573 !
2574 indnth = ihigt(ihig)
2575 Return
2576 !
2577 !
2578 Case (0)
2579 !
2580 ! Low part is exactly what we want
2581 !
2582 Exit
2583 !
2584 !
2585 Case (-5 : -1)
2586 !
2587 ! Only few values too many in low part
2588 !
2589 irngt(1) = ilowt(1)
2590 ilow = 1 + inth - jlow
2591 Do icrs = 2, inth
2592 iwrk = ilowt(icrs)
2593 xwrk = xdont(iwrk)
2594 Do idcr = icrs - 1, max(1, ilow), - 1
2595 If (xwrk < xdont(irngt(idcr))) Then
2596 irngt(idcr + 1) = irngt(idcr)
2597 Else
2598 Exit
2599 End If
2600 End Do
2601 irngt(idcr + 1) = iwrk
2602 ilow = ilow + 1
2603 End Do
2604 !
2605 xwrk1 = xdont(irngt(inth))
2606 ilow = 2 * inth - jlow
2607 Do icrs = inth + 1, jlow
2608 If (xdont(ilowt(icrs)) < xwrk1) Then
2609 xwrk = xdont(ilowt(icrs))
2610 Do idcr = inth - 1, max(1, ilow), - 1
2611 If (xwrk >= xdont(irngt(idcr))) Exit
2612 irngt(idcr + 1) = irngt(idcr)
2613 End Do
2614 irngt(idcr + 1) = ilowt(icrs)
2615 xwrk1 = xdont(irngt(inth))
2616 End If
2617 ilow = ilow + 1
2618 End Do
2619 !
2620 indnth = irngt(inth)
2621 Return
2622 !
2623 !
2624 Case (: -6)
2625 !
2626 ! last case: too many values in low part
2627 !
2628
2629 imil = (jlow + 1) / 2
2630 ifin = jlow
2631 !
2632 ! One chooses a pivot from 1st, last, and middle values
2633 !
2634 If (xdont(ilowt(imil)) < xdont(ilowt(1))) Then
2635 iwrk = ilowt(1)
2636 ilowt(1) = ilowt(imil)
2637 ilowt(imil) = iwrk
2638 End If
2639 If (xdont(ilowt(imil)) > xdont(ilowt(ifin))) Then
2640 iwrk = ilowt(ifin)
2641 ilowt(ifin) = ilowt(imil)
2642 ilowt(imil) = iwrk
2643 If (xdont(ilowt(imil)) < xdont(ilowt(1))) Then
2644 iwrk = ilowt(1)
2645 ilowt(1) = ilowt(imil)
2646 ilowt(imil) = iwrk
2647 End If
2648 End If
2649 If (ifin <= 3) Exit
2650 !
2651 xpiv = xdont(ilowt(1)) + real(inth, dp) / real(jlow + inth, dp) * &
2652 (xdont(ilowt(ifin)) - xdont(ilowt(1)))
2653
2654 !
2655 ! One takes values > XPIV to IHIGT
2656 !
2657 jhig = 0
2658 jlow = 0
2659 !
2660 If (xdont(ilowt(ifin)) > xpiv) Then
2661 icrs = 0
2662 Do
2663 icrs = icrs + 1
2664 If (xdont(ilowt(icrs)) > xpiv) Then
2665 jhig = jhig + 1
2666 ihigt(jhig) = ilowt(icrs)
2667 If (icrs >= ifin) Exit
2668 Else
2669 jlow = jlow + 1
2670 ilowt(jlow) = ilowt(icrs)
2671 If (jlow >= inth) Exit
2672 End If
2673 End Do
2674 !
2675 If (icrs < ifin) Then
2676 Do
2677 icrs = icrs + 1
2678 If (xdont(ilowt(icrs)) <= xpiv) Then
2679 jlow = jlow + 1
2680 ilowt(jlow) = ilowt(icrs)
2681 Else
2682 If (icrs >= ifin) Exit
2683 End If
2684 End Do
2685 End If
2686 Else
2687 Do icrs = 1, ifin
2688 If (xdont(ilowt(icrs)) > xpiv) Then
2689 jhig = jhig + 1
2690 ihigt(jhig) = ilowt(icrs)
2691 Else
2692 jlow = jlow + 1
2693 ilowt(jlow) = ilowt(icrs)
2694 If (jlow >= inth) Exit
2695 End If
2696 End Do
2697 !
2698 Do icrs = icrs + 1, ifin
2699 If (xdont(ilowt(icrs)) <= xpiv) Then
2700 jlow = jlow + 1
2701 ilowt(jlow) = ilowt(icrs)
2702 End If
2703 End Do
2704 End If
2705 !
2706 End Select
2707 !
2708 End Do
2709 !
2710 ! Now, we only need to find maximum of the 1:INTH set
2711 !
2712
2713 iwrk1 = ilowt(1)
2714 xwrk1 = xdont(iwrk1)
2715 Do icrs = 1 + 1, inth
2716 iwrk = ilowt(icrs)
2717 xwrk = xdont(iwrk)
2718 If (xwrk > xwrk1) Then
2719 xwrk1 = xwrk
2720 iwrk1 = iwrk
2721 End If
2722 End Do
2723 indnth = iwrk1
2724 Return
2725 !
2726 !
2727 End Function d_indnth
2728
2729 Function r_indnth (XDONT, NORD) Result (INDNTH)
2730 ! Return NORDth value of XDONT, i.e fractile of order NORD/SIZE(XDONT).
2731 ! __________________________________________________________
2732 ! This routine uses a pivoting strategy such as the one of
2733 ! finding the median based on the quicksort algorithm, but
2734 ! we skew the pivot choice to try to bring it to NORD as
2735 ! fast as possible. It uses 2 temporary arrays, where it
2736 ! stores the indices of the values smaller than the pivot
2737 ! (ILOWT), and the indices of values larger than the pivot
2738 ! that we might still need later on (IHIGT). It iterates
2739 ! until it can bring the number of values in ILOWT to
2740 ! exactly NORD, and then finds the maximum of this set.
2741 ! Michel Olagnon - Aug. 2000
2742 ! __________________________________________________________
2743 ! _________________________________________________________
2744 Real(kind = sp), Dimension (:), Intent (In) :: xdont
2745 Integer(kind = i4) :: INDNTH
2746 Integer(kind = i4), Intent (In) :: NORD
2747 ! __________________________________________________________
2748 Real(kind = sp) :: xpiv, xwrk, xwrk1, xmin, xmax
2749 !
2750 Integer(kind = i4), Dimension (NORD) :: IRNGT
2751 Integer(kind = i4), Dimension (SIZE(XDONT)) :: ILOWT, IHIGT
2752 Integer(kind = i4) :: NDON, JHIG, JLOW, IHIG, IWRK, IWRK1, IWRK2, IWRK3
2753 Integer(kind = i4) :: IMIL, IFIN, ICRS, IDCR, ILOW
2754 Integer(kind = i4) :: JLM2, JLM1, JHM2, JHM1, INTH
2755 !
2756 ndon = SIZE (xdont)
2757 inth = nord
2758 !
2759 ! First loop is used to fill-in ILOWT, IHIGT at the same time
2760 !
2761 If (ndon < 2) Then
2762 If (inth == 1) indnth = 1
2763 Return
2764 End If
2765 !
2766 ! One chooses a pivot, best estimate possible to put fractile near
2767 ! mid-point of the set of low values.
2768 !
2769 If (xdont(2) < xdont(1)) Then
2770 ilowt(1) = 2
2771 ihigt(1) = 1
2772 Else
2773 ilowt(1) = 1
2774 ihigt(1) = 2
2775 End If
2776 !
2777 If (ndon < 3) Then
2778 If (inth == 1) indnth = ilowt(1)
2779 If (inth == 2) indnth = ihigt(1)
2780 Return
2781 End If
2782 !
2783 If (xdont(3) < xdont(ihigt(1))) Then
2784 ihigt(2) = ihigt(1)
2785 If (xdont(3) < xdont(ilowt(1))) Then
2786 ihigt(1) = ilowt(1)
2787 ilowt(1) = 3
2788 Else
2789 ihigt(1) = 3
2790 End If
2791 Else
2792 ihigt(2) = 3
2793 End If
2794 !
2795 If (ndon < 4) Then
2796 If (inth == 1) indnth = ilowt(1)
2797 If (inth == 2) indnth = ihigt(1)
2798 If (inth == 3) indnth = ihigt(2)
2799 Return
2800 End If
2801 !
2802 If (xdont(ndon) < xdont(ihigt(1))) Then
2803 ihigt(3) = ihigt(2)
2804 ihigt(2) = ihigt(1)
2805 If (xdont(ndon) < xdont(ilowt(1))) Then
2806 ihigt(1) = ilowt(1)
2807 ilowt(1) = ndon
2808 Else
2809 ihigt(1) = ndon
2810 End If
2811 Else
2812 ihigt(3) = ndon
2813 End If
2814 !
2815 If (ndon < 5) Then
2816 If (inth == 1) indnth = ilowt(1)
2817 If (inth == 2) indnth = ihigt(1)
2818 If (inth == 3) indnth = ihigt(2)
2819 If (inth == 4) indnth = ihigt(3)
2820 Return
2821 End If
2822 !
2823
2824 jlow = 1
2825 jhig = 3
2826 xpiv = xdont(ilowt(1)) + real(2 * inth, sp) / real(ndon + inth, sp) * &
2827 (xdont(ihigt(3)) - xdont(ilowt(1)))
2828 If (xpiv >= xdont(ihigt(1))) Then
2829 xpiv = xdont(ilowt(1)) + real(2 * inth, sp) / real(ndon + inth, sp) * &
2830 (xdont(ihigt(2)) - xdont(ilowt(1)))
2831 If (xpiv >= xdont(ihigt(1))) &
2832 xpiv = xdont(ilowt(1)) + real(2 * inth, sp) / real(ndon + inth, sp) * &
2833 (xdont(ihigt(1)) - xdont(ilowt(1)))
2834 End If
2835 !
2836 ! One puts values > pivot in the end and those <= pivot
2837 ! at the beginning. This is split in 2 cases, so that
2838 ! we can skip the loop test a number of times.
2839 ! As we are also filling in the work arrays at the same time
2840 ! we stop filling in the IHIGT array as soon as we have more
2841 ! than enough values in ILOWT.
2842 !
2843 !
2844 If (xdont(ndon) > xpiv) Then
2845 icrs = 3
2846 Do
2847 icrs = icrs + 1
2848 If (xdont(icrs) > xpiv) Then
2849 If (icrs >= ndon) Exit
2850 jhig = jhig + 1
2851 ihigt(jhig) = icrs
2852 Else
2853 jlow = jlow + 1
2854 ilowt(jlow) = icrs
2855 If (jlow >= inth) Exit
2856 End If
2857 End Do
2858 !
2859 ! One restricts further processing because it is no use
2860 ! to store more high values
2861 !
2862 If (icrs < ndon - 1) Then
2863 Do
2864 icrs = icrs + 1
2865 If (xdont(icrs) <= xpiv) Then
2866 jlow = jlow + 1
2867 ilowt(jlow) = icrs
2868 Else If (icrs >= ndon) Then
2869 Exit
2870 End If
2871 End Do
2872 End If
2873 !
2874 !
2875 Else
2876 !
2877 ! Same as above, but this is not as easy to optimize, so the
2878 ! DO-loop is kept
2879 !
2880 Do icrs = 4, ndon - 1
2881 If (xdont(icrs) > xpiv) Then
2882 jhig = jhig + 1
2883 ihigt(jhig) = icrs
2884 Else
2885 jlow = jlow + 1
2886 ilowt(jlow) = icrs
2887 If (jlow >= inth) Exit
2888 End If
2889 End Do
2890 !
2891 If (icrs < ndon - 1) Then
2892 Do
2893 icrs = icrs + 1
2894 If (xdont(icrs) <= xpiv) Then
2895 If (icrs >= ndon) Exit
2896 jlow = jlow + 1
2897 ilowt(jlow) = icrs
2898 End If
2899 End Do
2900 End If
2901 End If
2902 !
2903 jlm2 = 0
2904 jlm1 = 0
2905 jhm2 = 0
2906 jhm1 = 0
2907 Do
2908 If (jlm2 == jlow .And. jhm2 == jhig) Then
2909 !
2910 ! We are oscillating. Perturbate by bringing JLOW closer by one
2911 ! to INTH
2912 !
2913 If (inth > jlow) Then
2914 xmin = xdont(ihigt(1))
2915 ihig = 1
2916 Do icrs = 2, jhig
2917 If (xdont(ihigt(icrs)) < xmin) Then
2918 xmin = xdont(ihigt(icrs))
2919 ihig = icrs
2920 End If
2921 End Do
2922 !
2923 jlow = jlow + 1
2924 ilowt(jlow) = ihigt(ihig)
2925 ihigt(ihig) = ihigt(jhig)
2926 jhig = jhig - 1
2927 Else
2928
2929 ilow = ilowt(1)
2930 xmax = xdont(ilow)
2931 Do icrs = 2, jlow
2932 If (xdont(ilowt(icrs)) > xmax) Then
2933 iwrk = ilowt(icrs)
2934 xmax = xdont(iwrk)
2935 ilowt(icrs) = ilow
2936 ilow = iwrk
2937 End If
2938 End Do
2939 jlow = jlow - 1
2940 End If
2941 End If
2942 jlm2 = jlm1
2943 jlm1 = jlow
2944 jhm2 = jhm1
2945 jhm1 = jhig
2946 !
2947 ! We try to bring the number of values in the low values set
2948 ! closer to INTH.
2949 !
2950 Select Case (inth - jlow)
2951 Case (2 :)
2952 !
2953 ! Not enough values in low part, at least 2 are missing
2954 !
2955 inth = inth - jlow
2956 jlow = 0
2957 Select Case (jhig)
2958 !!!!! CASE DEFAULT
2959 !!!!! write (unit=*,fmt=*) "Assertion failed"
2960 !!!!! STOP
2961 !
2962 ! We make a special case when we have so few values in
2963 ! the high values set that it is bad performance to choose a pivot
2964 ! and apply the general algorithm.
2965 !
2966 Case (2)
2967 If (xdont(ihigt(1)) <= xdont(ihigt(2))) Then
2968 jlow = jlow + 1
2969 ilowt(jlow) = ihigt(1)
2970 jlow = jlow + 1
2971 ilowt(jlow) = ihigt(2)
2972 Else
2973 jlow = jlow + 1
2974 ilowt(jlow) = ihigt(2)
2975 jlow = jlow + 1
2976 ilowt(jlow) = ihigt(1)
2977 End If
2978 Exit
2979 !
2980 Case (3)
2981 !
2982 !
2983 iwrk1 = ihigt(1)
2984 iwrk2 = ihigt(2)
2985 iwrk3 = ihigt(3)
2986 If (xdont(iwrk2) < xdont(iwrk1)) Then
2987 ihigt(1) = iwrk2
2988 ihigt(2) = iwrk1
2989 iwrk2 = iwrk1
2990 End If
2991 If (xdont(iwrk2) > xdont(iwrk3)) Then
2992 ihigt(3) = iwrk2
2993 ihigt(2) = iwrk3
2994 iwrk2 = iwrk3
2995 If (xdont(iwrk2) < xdont(ihigt(1))) Then
2996 ihigt(2) = ihigt(1)
2997 ihigt(1) = iwrk2
2998 End If
2999 End If
3000 jhig = 0
3001 Do icrs = jlow + 1, inth
3002 jhig = jhig + 1
3003 ilowt(icrs) = ihigt(jhig)
3004 End Do
3005 jlow = inth
3006 Exit
3007 !
3008 Case (4 :)
3009 !
3010 !
3011 ifin = jhig
3012 !
3013 ! One chooses a pivot from the 2 first values and the last one.
3014 ! This should ensure sufficient renewal between iterations to
3015 ! avoid worst case behavior effects.
3016 !
3017 iwrk1 = ihigt(1)
3018 iwrk2 = ihigt(2)
3019 iwrk3 = ihigt(ifin)
3020 If (xdont(iwrk2) < xdont(iwrk1)) Then
3021 ihigt(1) = iwrk2
3022 ihigt(2) = iwrk1
3023 iwrk2 = iwrk1
3024 End If
3025 If (xdont(iwrk2) > xdont(iwrk3)) Then
3026 ihigt(ifin) = iwrk2
3027 ihigt(2) = iwrk3
3028 iwrk2 = iwrk3
3029 If (xdont(iwrk2) < xdont(ihigt(1))) Then
3030 ihigt(2) = ihigt(1)
3031 ihigt(1) = iwrk2
3032 End If
3033 End If
3034 !
3035 iwrk1 = ihigt(1)
3036 jlow = jlow + 1
3037 ilowt(jlow) = iwrk1
3038 xpiv = xdont(iwrk1) + 0.5 * (xdont(ihigt(ifin)) - xdont(iwrk1))
3039 !
3040 ! One takes values <= pivot to ILOWT
3041 ! Again, 2 parts, one where we take care of the remaining
3042 ! high values because we might still need them, and the
3043 ! other when we know that we will have more than enough
3044 ! low values in the end.
3045 !
3046 jhig = 0
3047 Do icrs = 2, ifin
3048 If (xdont(ihigt(icrs)) <= xpiv) Then
3049 jlow = jlow + 1
3050 ilowt(jlow) = ihigt(icrs)
3051 If (jlow >= inth) Exit
3052 Else
3053 jhig = jhig + 1
3054 ihigt(jhig) = ihigt(icrs)
3055 End If
3056 End Do
3057 !
3058 Do icrs = icrs + 1, ifin
3059 If (xdont(ihigt(icrs)) <= xpiv) Then
3060 jlow = jlow + 1
3061 ilowt(jlow) = ihigt(icrs)
3062 End If
3063 End Do
3064 End Select
3065 !
3066 !
3067 Case (1)
3068 !
3069 ! Only 1 value is missing in low part
3070 !
3071 xmin = xdont(ihigt(1))
3072 ihig = 1
3073 Do icrs = 2, jhig
3074 If (xdont(ihigt(icrs)) < xmin) Then
3075 xmin = xdont(ihigt(icrs))
3076 ihig = icrs
3077 End If
3078 End Do
3079 !
3080 indnth = ihigt(ihig)
3081 Return
3082 !
3083 !
3084 Case (0)
3085 !
3086 ! Low part is exactly what we want
3087 !
3088 Exit
3089 !
3090 !
3091 Case (-5 : -1)
3092 !
3093 ! Only few values too many in low part
3094 !
3095 irngt(1) = ilowt(1)
3096 ilow = 1 + inth - jlow
3097 Do icrs = 2, inth
3098 iwrk = ilowt(icrs)
3099 xwrk = xdont(iwrk)
3100 Do idcr = icrs - 1, max(1, ilow), - 1
3101 If (xwrk < xdont(irngt(idcr))) Then
3102 irngt(idcr + 1) = irngt(idcr)
3103 Else
3104 Exit
3105 End If
3106 End Do
3107 irngt(idcr + 1) = iwrk
3108 ilow = ilow + 1
3109 End Do
3110 !
3111 xwrk1 = xdont(irngt(inth))
3112 ilow = 2 * inth - jlow
3113 Do icrs = inth + 1, jlow
3114 If (xdont(ilowt(icrs)) < xwrk1) Then
3115 xwrk = xdont(ilowt(icrs))
3116 Do idcr = inth - 1, max(1, ilow), - 1
3117 If (xwrk >= xdont(irngt(idcr))) Exit
3118 irngt(idcr + 1) = irngt(idcr)
3119 End Do
3120 irngt(idcr + 1) = ilowt(icrs)
3121 xwrk1 = xdont(irngt(inth))
3122 End If
3123 ilow = ilow + 1
3124 End Do
3125 !
3126 indnth = irngt(inth)
3127 Return
3128 !
3129 !
3130 Case (: -6)
3131 !
3132 ! last case: too many values in low part
3133 !
3134
3135 imil = (jlow + 1) / 2
3136 ifin = jlow
3137 !
3138 ! One chooses a pivot from 1st, last, and middle values
3139 !
3140 If (xdont(ilowt(imil)) < xdont(ilowt(1))) Then
3141 iwrk = ilowt(1)
3142 ilowt(1) = ilowt(imil)
3143 ilowt(imil) = iwrk
3144 End If
3145 If (xdont(ilowt(imil)) > xdont(ilowt(ifin))) Then
3146 iwrk = ilowt(ifin)
3147 ilowt(ifin) = ilowt(imil)
3148 ilowt(imil) = iwrk
3149 If (xdont(ilowt(imil)) < xdont(ilowt(1))) Then
3150 iwrk = ilowt(1)
3151 ilowt(1) = ilowt(imil)
3152 ilowt(imil) = iwrk
3153 End If
3154 End If
3155 If (ifin <= 3) Exit
3156 !
3157 xpiv = xdont(ilowt(1)) + real(inth, sp) / real(jlow + inth, sp) * &
3158 (xdont(ilowt(ifin)) - xdont(ilowt(1)))
3159
3160 !
3161 ! One takes values > XPIV to IHIGT
3162 !
3163 jhig = 0
3164 jlow = 0
3165 !
3166 If (xdont(ilowt(ifin)) > xpiv) Then
3167 icrs = 0
3168 Do
3169 icrs = icrs + 1
3170 If (xdont(ilowt(icrs)) > xpiv) Then
3171 jhig = jhig + 1
3172 ihigt(jhig) = ilowt(icrs)
3173 If (icrs >= ifin) Exit
3174 Else
3175 jlow = jlow + 1
3176 ilowt(jlow) = ilowt(icrs)
3177 If (jlow >= inth) Exit
3178 End If
3179 End Do
3180 !
3181 If (icrs < ifin) Then
3182 Do
3183 icrs = icrs + 1
3184 If (xdont(ilowt(icrs)) <= xpiv) Then
3185 jlow = jlow + 1
3186 ilowt(jlow) = ilowt(icrs)
3187 Else
3188 If (icrs >= ifin) Exit
3189 End If
3190 End Do
3191 End If
3192 Else
3193 Do icrs = 1, ifin
3194 If (xdont(ilowt(icrs)) > xpiv) Then
3195 jhig = jhig + 1
3196 ihigt(jhig) = ilowt(icrs)
3197 Else
3198 jlow = jlow + 1
3199 ilowt(jlow) = ilowt(icrs)
3200 If (jlow >= inth) Exit
3201 End If
3202 End Do
3203 !
3204 Do icrs = icrs + 1, ifin
3205 If (xdont(ilowt(icrs)) <= xpiv) Then
3206 jlow = jlow + 1
3207 ilowt(jlow) = ilowt(icrs)
3208 End If
3209 End Do
3210 End If
3211 !
3212 End Select
3213 !
3214 End Do
3215 !
3216 ! Now, we only need to find maximum of the 1:INTH set
3217 !
3218
3219 iwrk1 = ilowt(1)
3220 xwrk1 = xdont(iwrk1)
3221 Do icrs = 1 + 1, inth
3222 iwrk = ilowt(icrs)
3223 xwrk = xdont(iwrk)
3224 If (xwrk > xwrk1) Then
3225 xwrk1 = xwrk
3226 iwrk1 = iwrk
3227 End If
3228 End Do
3229 indnth = iwrk1
3230 Return
3231 !
3232 !
3233 End Function r_indnth
3234
3235 Function i_indnth (XDONT, NORD) Result (INDNTH)
3236 ! Return NORDth value of XDONT, i.e fractile of order NORD/SIZE(XDONT).
3237 ! __________________________________________________________
3238 ! This routine uses a pivoting strategy such as the one of
3239 ! finding the median based on the quicksort algorithm, but
3240 ! we skew the pivot choice to try to bring it to NORD as
3241 ! fast as possible. It uses 2 temporary arrays, where it
3242 ! stores the indices of the values smaller than the pivot
3243 ! (ILOWT), and the indices of values larger than the pivot
3244 ! that we might still need later on (IHIGT). It iterates
3245 ! until it can bring the number of values in ILOWT to
3246 ! exactly NORD, and then finds the maximum of this set.
3247 ! Michel Olagnon - Aug. 2000
3248 ! __________________________________________________________
3249 ! __________________________________________________________
3250 Integer(kind = i4), Dimension (:), Intent (In) :: XDONT
3251 Integer(kind = i4) :: INDNTH
3252 Integer(kind = i4), Intent (In) :: NORD
3253 ! __________________________________________________________
3254 Integer(kind = i4) :: XPIV, XWRK, XWRK1, XMIN, XMAX
3255 !
3256 Integer(kind = i4), Dimension (NORD) :: IRNGT
3257 Integer(kind = i4), Dimension (SIZE(XDONT)) :: ILOWT, IHIGT
3258 Integer(kind = i4) :: NDON, JHIG, JLOW, IHIG, IWRK, IWRK1, IWRK2, IWRK3
3259 Integer(kind = i4) :: IMIL, IFIN, ICRS, IDCR, ILOW
3260 Integer(kind = i4) :: JLM2, JLM1, JHM2, JHM1, INTH
3261 !
3262 ndon = SIZE (xdont)
3263 inth = nord
3264 !
3265 ! First loop is used to fill-in ILOWT, IHIGT at the same time
3266 !
3267 If (ndon < 2) Then
3268 If (inth == 1) indnth = 1
3269 Return
3270 End If
3271 !
3272 ! One chooses a pivot, best estimate possible to put fractile near
3273 ! mid-point of the set of low values.
3274 !
3275 If (xdont(2) < xdont(1)) Then
3276 ilowt(1) = 2
3277 ihigt(1) = 1
3278 Else
3279 ilowt(1) = 1
3280 ihigt(1) = 2
3281 End If
3282 !
3283 If (ndon < 3) Then
3284 If (inth == 1) indnth = ilowt(1)
3285 If (inth == 2) indnth = ihigt(1)
3286 Return
3287 End If
3288 !
3289 If (xdont(3) < xdont(ihigt(1))) Then
3290 ihigt(2) = ihigt(1)
3291 If (xdont(3) < xdont(ilowt(1))) Then
3292 ihigt(1) = ilowt(1)
3293 ilowt(1) = 3
3294 Else
3295 ihigt(1) = 3
3296 End If
3297 Else
3298 ihigt(2) = 3
3299 End If
3300 !
3301 If (ndon < 4) Then
3302 If (inth == 1) indnth = ilowt(1)
3303 If (inth == 2) indnth = ihigt(1)
3304 If (inth == 3) indnth = ihigt(2)
3305 Return
3306 End If
3307 !
3308 If (xdont(ndon) < xdont(ihigt(1))) Then
3309 ihigt(3) = ihigt(2)
3310 ihigt(2) = ihigt(1)
3311 If (xdont(ndon) < xdont(ilowt(1))) Then
3312 ihigt(1) = ilowt(1)
3313 ilowt(1) = ndon
3314 Else
3315 ihigt(1) = ndon
3316 End If
3317 Else
3318 ihigt(3) = ndon
3319 End If
3320 !
3321 If (ndon < 5) Then
3322 If (inth == 1) indnth = ilowt(1)
3323 If (inth == 2) indnth = ihigt(1)
3324 If (inth == 3) indnth = ihigt(2)
3325 If (inth == 4) indnth = ihigt(3)
3326 Return
3327 End If
3328 !
3329
3330 jlow = 1
3331 jhig = 3
3332 xpiv = xdont(ilowt(1)) + int(real(2 * inth, sp) / real(ndon + inth, sp), i4) * &
3333 (xdont(ihigt(3)) - xdont(ilowt(1)))
3334 If (xpiv >= xdont(ihigt(1))) Then
3335 xpiv = xdont(ilowt(1)) + int(real(2 * inth, sp) / real(ndon + inth, sp), i4) * &
3336 (xdont(ihigt(2)) - xdont(ilowt(1)))
3337 If (xpiv >= xdont(ihigt(1))) &
3338 xpiv = xdont(ilowt(1)) + int(real(2 * inth, sp) / real(ndon + inth, sp), i4) * &
3339 (xdont(ihigt(1)) - xdont(ilowt(1)))
3340 End If
3341 !
3342 ! One puts values > pivot in the end and those <= pivot
3343 ! at the beginning. This is split in 2 cases, so that
3344 ! we can skip the loop test a number of times.
3345 ! As we are also filling in the work arrays at the same time
3346 ! we stop filling in the IHIGT array as soon as we have more
3347 ! than enough values in ILOWT.
3348 !
3349 !
3350 If (xdont(ndon) > xpiv) Then
3351 icrs = 3
3352 Do
3353 icrs = icrs + 1
3354 If (xdont(icrs) > xpiv) Then
3355 If (icrs >= ndon) Exit
3356 jhig = jhig + 1
3357 ihigt(jhig) = icrs
3358 Else
3359 jlow = jlow + 1
3360 ilowt(jlow) = icrs
3361 If (jlow >= inth) Exit
3362 End If
3363 End Do
3364 !
3365 ! One restricts further processing because it is no use
3366 ! to store more high values
3367 !
3368 If (icrs < ndon - 1) Then
3369 Do
3370 icrs = icrs + 1
3371 If (xdont(icrs) <= xpiv) Then
3372 jlow = jlow + 1
3373 ilowt(jlow) = icrs
3374 Else If (icrs >= ndon) Then
3375 Exit
3376 End If
3377 End Do
3378 End If
3379 !
3380 !
3381 Else
3382 !
3383 ! Same as above, but this is not as easy to optimize, so the
3384 ! DO-loop is kept
3385 !
3386 Do icrs = 4, ndon - 1
3387 If (xdont(icrs) > xpiv) Then
3388 jhig = jhig + 1
3389 ihigt(jhig) = icrs
3390 Else
3391 jlow = jlow + 1
3392 ilowt(jlow) = icrs
3393 If (jlow >= inth) Exit
3394 End If
3395 End Do
3396 !
3397 If (icrs < ndon - 1) Then
3398 Do
3399 icrs = icrs + 1
3400 If (xdont(icrs) <= xpiv) Then
3401 If (icrs >= ndon) Exit
3402 jlow = jlow + 1
3403 ilowt(jlow) = icrs
3404 End If
3405 End Do
3406 End If
3407 End If
3408 !
3409 jlm2 = 0
3410 jlm1 = 0
3411 jhm2 = 0
3412 jhm1 = 0
3413 Do
3414 If (jlm2 == jlow .And. jhm2 == jhig) Then
3415 !
3416 ! We are oscillating. Perturbate by bringing JLOW closer by one
3417 ! to INTH
3418 !
3419 If (inth > jlow) Then
3420 xmin = xdont(ihigt(1))
3421 ihig = 1
3422 Do icrs = 2, jhig
3423 If (xdont(ihigt(icrs)) < xmin) Then
3424 xmin = xdont(ihigt(icrs))
3425 ihig = icrs
3426 End If
3427 End Do
3428 !
3429 jlow = jlow + 1
3430 ilowt(jlow) = ihigt(ihig)
3431 ihigt(ihig) = ihigt(jhig)
3432 jhig = jhig - 1
3433 Else
3434
3435 ilow = ilowt(1)
3436 xmax = xdont(ilow)
3437 Do icrs = 2, jlow
3438 If (xdont(ilowt(icrs)) > xmax) Then
3439 iwrk = ilowt(icrs)
3440 xmax = xdont(iwrk)
3441 ilowt(icrs) = ilow
3442 ilow = iwrk
3443 End If
3444 End Do
3445 jlow = jlow - 1
3446 End If
3447 End If
3448 jlm2 = jlm1
3449 jlm1 = jlow
3450 jhm2 = jhm1
3451 jhm1 = jhig
3452 !
3453 ! We try to bring the number of values in the low values set
3454 ! closer to INTH.
3455 !
3456 Select Case (inth - jlow)
3457 Case (2 :)
3458 !
3459 ! Not enough values in low part, at least 2 are missing
3460 !
3461 inth = inth - jlow
3462 jlow = 0
3463 Select Case (jhig)
3464 !!!!! CASE DEFAULT
3465 !!!!! write (unit=*,fmt=*) "Assertion failed"
3466 !!!!! STOP
3467 !
3468 ! We make a special case when we have so few values in
3469 ! the high values set that it is bad performance to choose a pivot
3470 ! and apply the general algorithm.
3471 !
3472 Case (2)
3473 If (xdont(ihigt(1)) <= xdont(ihigt(2))) Then
3474 jlow = jlow + 1
3475 ilowt(jlow) = ihigt(1)
3476 jlow = jlow + 1
3477 ilowt(jlow) = ihigt(2)
3478 Else
3479 jlow = jlow + 1
3480 ilowt(jlow) = ihigt(2)
3481 jlow = jlow + 1
3482 ilowt(jlow) = ihigt(1)
3483 End If
3484 Exit
3485 !
3486 Case (3)
3487 !
3488 !
3489 iwrk1 = ihigt(1)
3490 iwrk2 = ihigt(2)
3491 iwrk3 = ihigt(3)
3492 If (xdont(iwrk2) < xdont(iwrk1)) Then
3493 ihigt(1) = iwrk2
3494 ihigt(2) = iwrk1
3495 iwrk2 = iwrk1
3496 End If
3497 If (xdont(iwrk2) > xdont(iwrk3)) Then
3498 ihigt(3) = iwrk2
3499 ihigt(2) = iwrk3
3500 iwrk2 = iwrk3
3501 If (xdont(iwrk2) < xdont(ihigt(1))) Then
3502 ihigt(2) = ihigt(1)
3503 ihigt(1) = iwrk2
3504 End If
3505 End If
3506 jhig = 0
3507 Do icrs = jlow + 1, inth
3508 jhig = jhig + 1
3509 ilowt(icrs) = ihigt(jhig)
3510 End Do
3511 jlow = inth
3512 Exit
3513 !
3514 Case (4 :)
3515 !
3516 !
3517 ifin = jhig
3518 !
3519 ! One chooses a pivot from the 2 first values and the last one.
3520 ! This should ensure sufficient renewal between iterations to
3521 ! avoid worst case behavior effects.
3522 !
3523 iwrk1 = ihigt(1)
3524 iwrk2 = ihigt(2)
3525 iwrk3 = ihigt(ifin)
3526 If (xdont(iwrk2) < xdont(iwrk1)) Then
3527 ihigt(1) = iwrk2
3528 ihigt(2) = iwrk1
3529 iwrk2 = iwrk1
3530 End If
3531 If (xdont(iwrk2) > xdont(iwrk3)) Then
3532 ihigt(ifin) = iwrk2
3533 ihigt(2) = iwrk3
3534 iwrk2 = iwrk3
3535 If (xdont(iwrk2) < xdont(ihigt(1))) Then
3536 ihigt(2) = ihigt(1)
3537 ihigt(1) = iwrk2
3538 End If
3539 End If
3540 !
3541 iwrk1 = ihigt(1)
3542 jlow = jlow + 1
3543 ilowt(jlow) = iwrk1
3544 xpiv = xdont(iwrk1) + (xdont(ihigt(ifin)) - xdont(iwrk1)) / 2
3545 !
3546 ! One takes values <= pivot to ILOWT
3547 ! Again, 2 parts, one where we take care of the remaining
3548 ! high values because we might still need them, and the
3549 ! other when we know that we will have more than enough
3550 ! low values in the end.
3551 !
3552 jhig = 0
3553 Do icrs = 2, ifin
3554 If (xdont(ihigt(icrs)) <= xpiv) Then
3555 jlow = jlow + 1
3556 ilowt(jlow) = ihigt(icrs)
3557 If (jlow >= inth) Exit
3558 Else
3559 jhig = jhig + 1
3560 ihigt(jhig) = ihigt(icrs)
3561 End If
3562 End Do
3563 !
3564 Do icrs = icrs + 1, ifin
3565 If (xdont(ihigt(icrs)) <= xpiv) Then
3566 jlow = jlow + 1
3567 ilowt(jlow) = ihigt(icrs)
3568 End If
3569 End Do
3570 End Select
3571 !
3572 !
3573 Case (1)
3574 !
3575 ! Only 1 value is missing in low part
3576 !
3577 xmin = xdont(ihigt(1))
3578 ihig = 1
3579 Do icrs = 2, jhig
3580 If (xdont(ihigt(icrs)) < xmin) Then
3581 xmin = xdont(ihigt(icrs))
3582 ihig = icrs
3583 End If
3584 End Do
3585 !
3586 indnth = ihigt(ihig)
3587 Return
3588 !
3589 !
3590 Case (0)
3591 !
3592 ! Low part is exactly what we want
3593 !
3594 Exit
3595 !
3596 !
3597 Case (-5 : -1)
3598 !
3599 ! Only few values too many in low part
3600 !
3601 irngt(1) = ilowt(1)
3602 ilow = 1 + inth - jlow
3603 Do icrs = 2, inth
3604 iwrk = ilowt(icrs)
3605 xwrk = xdont(iwrk)
3606 Do idcr = icrs - 1, max(1, ilow), - 1
3607 If (xwrk < xdont(irngt(idcr))) Then
3608 irngt(idcr + 1) = irngt(idcr)
3609 Else
3610 Exit
3611 End If
3612 End Do
3613 irngt(idcr + 1) = iwrk
3614 ilow = ilow + 1
3615 End Do
3616 !
3617 xwrk1 = xdont(irngt(inth))
3618 ilow = 2 * inth - jlow
3619 Do icrs = inth + 1, jlow
3620 If (xdont(ilowt(icrs)) < xwrk1) Then
3621 xwrk = xdont(ilowt(icrs))
3622 Do idcr = inth - 1, max(1, ilow), - 1
3623 If (xwrk >= xdont(irngt(idcr))) Exit
3624 irngt(idcr + 1) = irngt(idcr)
3625 End Do
3626 irngt(idcr + 1) = ilowt(icrs)
3627 xwrk1 = xdont(irngt(inth))
3628 End If
3629 ilow = ilow + 1
3630 End Do
3631 !
3632 indnth = irngt(inth)
3633 Return
3634 !
3635 !
3636 Case (: -6)
3637 !
3638 ! last case: too many values in low part
3639 !
3640
3641 imil = (jlow + 1) / 2
3642 ifin = jlow
3643 !
3644 ! One chooses a pivot from 1st, last, and middle values
3645 !
3646 If (xdont(ilowt(imil)) < xdont(ilowt(1))) Then
3647 iwrk = ilowt(1)
3648 ilowt(1) = ilowt(imil)
3649 ilowt(imil) = iwrk
3650 End If
3651 If (xdont(ilowt(imil)) > xdont(ilowt(ifin))) Then
3652 iwrk = ilowt(ifin)
3653 ilowt(ifin) = ilowt(imil)
3654 ilowt(imil) = iwrk
3655 If (xdont(ilowt(imil)) < xdont(ilowt(1))) Then
3656 iwrk = ilowt(1)
3657 ilowt(1) = ilowt(imil)
3658 ilowt(imil) = iwrk
3659 End If
3660 End If
3661 If (ifin <= 3) Exit
3662 !
3663 xpiv = xdont(ilowt(1)) + int(real(inth, sp) / real(jlow + inth, sp), i4) * &
3664 (xdont(ilowt(ifin)) - xdont(ilowt(1)))
3665
3666 !
3667 ! One takes values > XPIV to IHIGT
3668 !
3669 jhig = 0
3670 jlow = 0
3671 !
3672 If (xdont(ilowt(ifin)) > xpiv) Then
3673 icrs = 0
3674 Do
3675 icrs = icrs + 1
3676 If (xdont(ilowt(icrs)) > xpiv) Then
3677 jhig = jhig + 1
3678 ihigt(jhig) = ilowt(icrs)
3679 If (icrs >= ifin) Exit
3680 Else
3681 jlow = jlow + 1
3682 ilowt(jlow) = ilowt(icrs)
3683 If (jlow >= inth) Exit
3684 End If
3685 End Do
3686 !
3687 If (icrs < ifin) Then
3688 Do
3689 icrs = icrs + 1
3690 If (xdont(ilowt(icrs)) <= xpiv) Then
3691 jlow = jlow + 1
3692 ilowt(jlow) = ilowt(icrs)
3693 Else
3694 If (icrs >= ifin) Exit
3695 End If
3696 End Do
3697 End If
3698 Else
3699 Do icrs = 1, ifin
3700 If (xdont(ilowt(icrs)) > xpiv) Then
3701 jhig = jhig + 1
3702 ihigt(jhig) = ilowt(icrs)
3703 Else
3704 jlow = jlow + 1
3705 ilowt(jlow) = ilowt(icrs)
3706 If (jlow >= inth) Exit
3707 End If
3708 End Do
3709 !
3710 Do icrs = icrs + 1, ifin
3711 If (xdont(ilowt(icrs)) <= xpiv) Then
3712 jlow = jlow + 1
3713 ilowt(jlow) = ilowt(icrs)
3714 End If
3715 End Do
3716 End If
3717 !
3718 End Select
3719 !
3720 End Do
3721 !
3722 ! Now, we only need to find maximum of the 1:INTH set
3723 !
3724
3725 iwrk1 = ilowt(1)
3726 xwrk1 = xdont(iwrk1)
3727 Do icrs = 1 + 1, inth
3728 iwrk = ilowt(icrs)
3729 xwrk = xdont(iwrk)
3730 If (xwrk > xwrk1) Then
3731 xwrk1 = xwrk
3732 iwrk1 = iwrk
3733 End If
3734 End Do
3735 indnth = iwrk1
3736 Return
3737 !
3738 !
3739 End Function i_indnth
3740
3741 Subroutine d_inspar (XDONT, NORD)
3742 ! Sorts partially XDONT, bringing the NORD lowest values at the
3743 ! begining of the array
3744 ! __________________________________________________________
3745 ! This subroutine uses insertion sort, limiting insertion
3746 ! to the first NORD values. It does not use any work array
3747 ! and is faster when NORD is very small (2-5), but worst case
3748 ! behavior can happen fairly probably (initially inverse sorted)
3749 ! In many cases, the refined quicksort method is faster.
3750 ! Michel Olagnon - Feb. 2000
3751 ! __________________________________________________________
3752 ! __________________________________________________________
3753 real(kind = dp), Dimension (:), Intent (InOut) :: xdont
3754 Integer(kind = i4), Intent (In) :: NORD
3755 ! __________________________________________________________
3756 real(kind = dp) :: xwrk, xwrk1
3757 !
3758 Integer(kind = i4) :: ICRS, IDCR
3759 !
3760 Do icrs = 2, nord
3761 xwrk = xdont(icrs)
3762 Do idcr = icrs - 1, 1, - 1
3763 If (xwrk >= xdont(idcr)) Exit
3764 xdont(idcr + 1) = xdont(idcr)
3765 End Do
3766 xdont(idcr + 1) = xwrk
3767 End Do
3768 !
3769 xwrk1 = xdont(nord)
3770 Do icrs = nord + 1, SIZE (xdont)
3771 If (xdont(icrs) < xwrk1) Then
3772 xwrk = xdont(icrs)
3773 xdont(icrs) = xwrk1
3774 Do idcr = nord - 1, 1, - 1
3775 If (xwrk >= xdont(idcr)) Exit
3776 xdont(idcr + 1) = xdont(idcr)
3777 End Do
3778 xdont(idcr + 1) = xwrk
3779 xwrk1 = xdont(nord)
3780 End If
3781 End Do
3782 !
3783 !
3784 End Subroutine d_inspar
3785
3786 Subroutine r_inspar (XDONT, NORD)
3787 ! Sorts partially XDONT, bringing the NORD lowest values at the
3788 ! begining of the array
3789 ! __________________________________________________________
3790 ! This subroutine uses insertion sort, limiting insertion
3791 ! to the first NORD values. It does not use any work array
3792 ! and is faster when NORD is very small (2-5), but worst case
3793 ! behavior can happen fairly probably (initially inverse sorted)
3794 ! In many cases, the refined quicksort method is faster.
3795 ! Michel Olagnon - Feb. 2000
3796 ! __________________________________________________________
3797 ! _________________________________________________________
3798 Real(kind = sp), Dimension (:), Intent (InOut) :: xdont
3799 Integer(kind = i4), Intent (In) :: NORD
3800 ! __________________________________________________________
3801 Real(kind = sp) :: xwrk, xwrk1
3802 !
3803 Integer(kind = i4) :: ICRS, IDCR
3804 !
3805 Do icrs = 2, nord
3806 xwrk = xdont(icrs)
3807 Do idcr = icrs - 1, 1, - 1
3808 If (xwrk >= xdont(idcr)) Exit
3809 xdont(idcr + 1) = xdont(idcr)
3810 End Do
3811 xdont(idcr + 1) = xwrk
3812 End Do
3813 !
3814 xwrk1 = xdont(nord)
3815 Do icrs = nord + 1, SIZE (xdont)
3816 If (xdont(icrs) < xwrk1) Then
3817 xwrk = xdont(icrs)
3818 xdont(icrs) = xwrk1
3819 Do idcr = nord - 1, 1, - 1
3820 If (xwrk >= xdont(idcr)) Exit
3821 xdont(idcr + 1) = xdont(idcr)
3822 End Do
3823 xdont(idcr + 1) = xwrk
3824 xwrk1 = xdont(nord)
3825 End If
3826 End Do
3827 !
3828 !
3829 End Subroutine r_inspar
3830
3831 Subroutine i_inspar (XDONT, NORD)
3832 ! Sorts partially XDONT, bringing the NORD lowest values at the
3833 ! begining of the array
3834 ! __________________________________________________________
3835 ! This subroutine uses insertion sort, limiting insertion
3836 ! to the first NORD values. It does not use any work array
3837 ! and is faster when NORD is very small (2-5), but worst case
3838 ! behavior can happen fairly probably (initially inverse sorted)
3839 ! In many cases, the refined quicksort method is faster.
3840 ! Michel Olagnon - Feb. 2000
3841 ! __________________________________________________________
3842 ! __________________________________________________________
3843 Integer(kind = i4), Dimension (:), Intent (InOut) :: XDONT
3844 Integer(kind = i4), Intent (In) :: NORD
3845 ! __________________________________________________________
3846 Integer(kind = i4) :: XWRK, XWRK1
3847 !
3848 Integer(kind = i4) :: ICRS, IDCR
3849 !
3850 Do icrs = 2, nord
3851 xwrk = xdont(icrs)
3852 Do idcr = icrs - 1, 1, - 1
3853 If (xwrk >= xdont(idcr)) Exit
3854 xdont(idcr + 1) = xdont(idcr)
3855 End Do
3856 xdont(idcr + 1) = xwrk
3857 End Do
3858 !
3859 xwrk1 = xdont(nord)
3860 Do icrs = nord + 1, SIZE (xdont)
3861 If (xdont(icrs) < xwrk1) Then
3862 xwrk = xdont(icrs)
3863 xdont(icrs) = xwrk1
3864 Do idcr = nord - 1, 1, - 1
3865 If (xwrk >= xdont(idcr)) Exit
3866 xdont(idcr + 1) = xdont(idcr)
3867 End Do
3868 xdont(idcr + 1) = xwrk
3869 xwrk1 = xdont(nord)
3870 End If
3871 End Do
3872 !
3873 !
3874 End Subroutine i_inspar
3875
3876 Subroutine d_inssor (XDONT)
3877 ! Sorts XDONT into increasing order (Insertion sort)
3878 ! __________________________________________________________
3879 ! This subroutine uses insertion sort. It does not use any
3880 ! work array and is faster when XDONT is of very small size
3881 ! (< 20), or already almost sorted, but worst case behavior
3882 ! can happen fairly probably (initially inverse sorted).
3883 ! In many cases, the quicksort or merge sort method is faster.
3884 ! Michel Olagnon - Apr. 2000
3885 ! __________________________________________________________
3886 ! __________________________________________________________
3887 ! __________________________________________________________
3888 real(kind = dp), Dimension (:), Intent (InOut) :: xdont
3889 ! __________________________________________________________
3890 real(Kind = dp) :: xwrk, xmin
3891 !
3892 ! __________________________________________________________
3893 !
3894 Integer(kind = i4) :: ICRS, IDCR, NDON
3895 !
3896 ndon = Size (xdont)
3897 !
3898 ! We first bring the minimum to the first location in the array.
3899 ! That way, we will have a "guard", and when looking for the
3900 ! right place to insert a value, no loop test is necessary.
3901 !
3902 If (xdont(1) < xdont(ndon)) Then
3903 xmin = xdont(1)
3904 Else
3905 xmin = xdont(ndon)
3906 xdont(ndon) = xdont(1)
3907 end if
3908 Do idcr = ndon - 1, 2, -1
3909 xwrk = xdont(idcr)
3910 IF (xwrk < xmin) Then
3911 xdont(idcr) = xmin
3912 xmin = xwrk
3913 End If
3914 End Do
3915 xdont(1) = xmin
3916 !
3917 ! The first value is now the minimum
3918 ! Loop over the array, and when a value is smaller than
3919 ! the previous one, loop down to insert it at its right place.
3920 !
3921 Do icrs = 3, ndon
3922 xwrk = xdont(icrs)
3923 idcr = icrs - 1
3924 If (xwrk < xdont(idcr)) Then
3925 xdont(icrs) = xdont(idcr)
3926 idcr = idcr - 1
3927 Do
3928 If (xwrk >= xdont(idcr)) Exit
3929 xdont(idcr + 1) = xdont(idcr)
3930 idcr = idcr - 1
3931 End Do
3932 xdont(idcr + 1) = xwrk
3933 End If
3934 End Do
3935 !
3936 Return
3937 !
3938 End Subroutine d_inssor
3939
3940 Subroutine r_inssor (XDONT)
3941 ! Sorts XDONT into increasing order (Insertion sort)
3942 ! __________________________________________________________
3943 ! This subroutine uses insertion sort. It does not use any
3944 ! work array and is faster when XDONT is of very small size
3945 ! (< 20), or already almost sorted, but worst case behavior
3946 ! can happen fairly probably (initially inverse sorted).
3947 ! In many cases, the quicksort or merge sort method is faster.
3948 ! Michel Olagnon - Apr. 2000
3949 ! __________________________________________________________
3950 ! __________________________________________________________
3951 ! _________________________________________________________
3952 Real(kind = sp), Dimension (:), Intent (InOut) :: xdont
3953 ! __________________________________________________________
3954 Real(kind = sp) :: xwrk, xmin
3955 !
3956 ! __________________________________________________________
3957 !
3958 Integer(kind = i4) :: ICRS, IDCR, NDON
3959 !
3960 ndon = Size (xdont)
3961 !
3962 ! We first bring the minimum to the first location in the array.
3963 ! That way, we will have a "guard", and when looking for the
3964 ! right place to insert a value, no loop test is necessary.
3965 !
3966 If (xdont(1) < xdont(ndon)) Then
3967 xmin = xdont(1)
3968 Else
3969 xmin = xdont(ndon)
3970 xdont(ndon) = xdont(1)
3971 end if
3972 Do idcr = ndon - 1, 2, -1
3973 xwrk = xdont(idcr)
3974 IF (xwrk < xmin) Then
3975 xdont(idcr) = xmin
3976 xmin = xwrk
3977 End If
3978 End Do
3979 xdont(1) = xmin
3980 !
3981 ! The first value is now the minimum
3982 ! Loop over the array, and when a value is smaller than
3983 ! the previous one, loop down to insert it at its right place.
3984 !
3985 Do icrs = 3, ndon
3986 xwrk = xdont(icrs)
3987 idcr = icrs - 1
3988 If (xwrk < xdont(idcr)) Then
3989 xdont(icrs) = xdont(idcr)
3990 idcr = idcr - 1
3991 Do
3992 If (xwrk >= xdont(idcr)) Exit
3993 xdont(idcr + 1) = xdont(idcr)
3994 idcr = idcr - 1
3995 End Do
3996 xdont(idcr + 1) = xwrk
3997 End If
3998 End Do
3999 !
4000 Return
4001 !
4002 End Subroutine r_inssor
4003
4004 Subroutine i_inssor (XDONT)
4005 ! Sorts XDONT into increasing order (Insertion sort)
4006 ! __________________________________________________________
4007 ! This subroutine uses insertion sort. It does not use any
4008 ! work array and is faster when XDONT is of very small size
4009 ! (< 20), or already almost sorted, but worst case behavior
4010 ! can happen fairly probably (initially inverse sorted).
4011 ! In many cases, the quicksort or merge sort method is faster.
4012 ! Michel Olagnon - Apr. 2000
4013 ! __________________________________________________________
4014 ! __________________________________________________________
4015 ! __________________________________________________________
4016 Integer(kind = i4), Dimension (:), Intent (InOut) :: XDONT
4017 ! __________________________________________________________
4018 Integer(kind = i4) :: XWRK, XMIN
4019 !
4020 ! __________________________________________________________
4021 !
4022 Integer(kind = i4) :: ICRS, IDCR, NDON
4023 !
4024 ndon = Size (xdont)
4025 !
4026 ! We first bring the minimum to the first location in the array.
4027 ! That way, we will have a "guard", and when looking for the
4028 ! right place to insert a value, no loop test is necessary.
4029 !
4030 If (xdont(1) < xdont(ndon)) Then
4031 xmin = xdont(1)
4032 Else
4033 xmin = xdont(ndon)
4034 xdont(ndon) = xdont(1)
4035 end if
4036 Do idcr = ndon - 1, 2, -1
4037 xwrk = xdont(idcr)
4038 IF (xwrk < xmin) Then
4039 xdont(idcr) = xmin
4040 xmin = xwrk
4041 End If
4042 End Do
4043 xdont(1) = xmin
4044 !
4045 ! The first value is now the minimum
4046 ! Loop over the array, and when a value is smaller than
4047 ! the previous one, loop down to insert it at its right place.
4048 !
4049 Do icrs = 3, ndon
4050 xwrk = xdont(icrs)
4051 idcr = icrs - 1
4052 If (xwrk < xdont(idcr)) Then
4053 xdont(icrs) = xdont(idcr)
4054 idcr = idcr - 1
4055 Do
4056 If (xwrk >= xdont(idcr)) Exit
4057 xdont(idcr + 1) = xdont(idcr)
4058 idcr = idcr - 1
4059 End Do
4060 xdont(idcr + 1) = xwrk
4061 End If
4062 End Do
4063 !
4064 Return
4065 !
4066 End Subroutine i_inssor
4067
4068 Subroutine c_inssor (XDONT)
4069 ! Sorts XDONT into increasing order (Insertion sort)
4070 ! __________________________________________________________
4071 ! This subroutine uses insertion sort. It does not use any
4072 ! work array and is faster when XDONT is of very small size
4073 ! (< 20), or already almost sorted, but worst case behavior
4074 ! can happen fairly probably (initially inverse sorted).
4075 ! In many cases, the quicksort or merge sort method is faster.
4076 ! Michel Olagnon - Apr. 2000
4077 ! __________________________________________________________
4078 ! __________________________________________________________
4079 ! __________________________________________________________
4080 character(*), Dimension (:), Intent (InOut) :: XDONT
4081 ! __________________________________________________________
4082 character(len(XDONT)) :: XWRK, XMIN
4083 !
4084 ! __________________________________________________________
4085 !
4086 Integer(kind = i4) :: ICRS, IDCR, NDON
4087 !
4088 ndon = Size (xdont)
4089 !
4090 ! We first bring the minimum to the first location in the array.
4091 ! That way, we will have a "guard", and when looking for the
4092 ! right place to insert a value, no loop test is necessary.
4093 !
4094 If (xdont(1) < xdont(ndon)) Then
4095 xmin = xdont(1)
4096 Else
4097 xmin = xdont(ndon)
4098 xdont(ndon) = xdont(1)
4099 end if
4100 Do idcr = ndon - 1, 2, -1
4101 xwrk = xdont(idcr)
4102 IF (xwrk < xmin) Then
4103 xdont(idcr) = xmin
4104 xmin = xwrk
4105 End If
4106 End Do
4107 xdont(1) = xmin
4108 !
4109 ! The first value is now the minimum
4110 ! Loop over the array, and when a value is smaller than
4111 ! the previous one, loop down to insert it at its right place.
4112 !
4113 Do icrs = 3, ndon
4114 xwrk = xdont(icrs)
4115 idcr = icrs - 1
4116 If (xwrk < xdont(idcr)) Then
4117 xdont(icrs) = xdont(idcr)
4118 idcr = idcr - 1
4119 Do
4120 If (xwrk >= xdont(idcr)) Exit
4121 xdont(idcr + 1) = xdont(idcr)
4122 idcr = idcr - 1
4123 End Do
4124 xdont(idcr + 1) = xwrk
4125 End If
4126 End Do
4127 !
4128 Return
4129 !
4130 End Subroutine c_inssor
4131
4132 Function d_median (XDONT) Result (median)
4133 ! Return median value of XDONT
4134 ! If even number of data, average of the two "medians".
4135 ! __________________________________________________________
4136 ! This routine uses a pivoting strategy such as the one of
4137 ! finding the median based on the quicksort algorithm, but
4138 ! we skew the pivot choice to try to bring it to NORD as
4139 ! fast as possible. It uses 2 temporary arrays, where it
4140 ! stores the indices of the values smaller than the pivot
4141 ! (ILOWT), and the indices of values larger than the pivot
4142 ! that we might still need later on (IHIGT). It iterates
4143 ! until it can bring the number of values in ILOWT to
4144 ! exactly NORD, and then finds the maximum of this set.
4145 ! Michel Olagnon - Aug. 2000
4146 ! __________________________________________________________
4147 ! __________________________________________________________
4148 real(Kind = dp), Dimension (:), Intent (In) :: xdont
4149 real(Kind = dp) :: median
4150 ! __________________________________________________________
4151 real(Kind = dp), Dimension (SIZE(XDONT)) :: xlowt, xhigt
4152 real(Kind = dp) :: xpiv, xwrk, xwrk1, xwrk2, xwrk3, xmin, xmax
4153 !!
4154 Logical :: IFODD
4155 Integer(kind = i4) :: NDON, JHIG, JLOW, IHIG!, NORD
4156 Integer(kind = i4) :: IMIL, IFIN, ICRS, IDCR!, ILOW
4157 Integer(kind = i4) :: JLM2, JLM1, JHM2, JHM1, INTH
4158 !
4159 ndon = SIZE (xdont)
4160 inth = ndon / 2 + 1
4161 ifodd = (2 * inth == ndon + 1)
4162 !
4163 ! First loop is used to fill-in XLOWT, XHIGT at the same time
4164 !
4165 If (ndon < 3) Then
4166 If (ndon > 0) median = 0.5 * (xdont(1) + xdont(ndon))
4167 Return
4168 End If
4169 !
4170 ! One chooses a pivot, best estimate possible to put fractile near
4171 ! mid-point of the set of low values.
4172 !
4173 If (xdont(2) < xdont(1)) Then
4174 xlowt(1) = xdont(2)
4175 xhigt(1) = xdont(1)
4176 Else
4177 xlowt(1) = xdont(1)
4178 xhigt(1) = xdont(2)
4179 End If
4180 !
4181 !
4182 If (xdont(3) < xhigt(1)) Then
4183 xhigt(2) = xhigt(1)
4184 If (xdont(3) < xlowt(1)) Then
4185 xhigt(1) = xlowt(1)
4186 xlowt(1) = xdont(3)
4187 Else
4188 xhigt(1) = xdont(3)
4189 End If
4190 Else
4191 xhigt(2) = xdont(3)
4192 End If
4193 !
4194 If (ndon < 4) Then ! 3 values
4195 median = xhigt(1)
4196 Return
4197 End If
4198 !
4199 If (xdont(ndon) < xhigt(1)) Then
4200 xhigt(3) = xhigt(2)
4201 xhigt(2) = xhigt(1)
4202 If (xdont(ndon) < xlowt(1)) Then
4203 xhigt(1) = xlowt(1)
4204 xlowt(1) = xdont(ndon)
4205 Else
4206 xhigt(1) = xdont(ndon)
4207 End If
4208 Else
4209 If (xdont(ndon) < xhigt(2)) Then
4210 xhigt(3) = xhigt(2)
4211 xhigt(2) = xdont(ndon)
4212 Else
4213 xhigt(3) = xdont(ndon)
4214 End If
4215 End If
4216 !
4217 If (ndon < 5) Then ! 4 values
4218 median = 0.5 * (xhigt(1) + xhigt(2))
4219 Return
4220 End If
4221 !
4222 jlow = 1
4223 jhig = 3
4224 xpiv = xlowt(1) + 2.0 * (xhigt(3) - xlowt(1)) / 3.0
4225 If (xpiv >= xhigt(1)) Then
4226 xpiv = xlowt(1) + 2.0 * (xhigt(2) - xlowt(1)) / 3.0
4227 If (xpiv >= xhigt(1)) xpiv = xlowt(1) + 2.0 * (xhigt(1) - xlowt(1)) / 3.0
4228 End If
4229 !
4230 ! One puts values > pivot in the end and those <= pivot
4231 ! at the beginning. This is split in 2 cases, so that
4232 ! we can skip the loop test a number of times.
4233 ! As we are also filling in the work arrays at the same time
4234 ! we stop filling in the XHIGT array as soon as we have more
4235 ! than enough values in XLOWT.
4236 !
4237 !
4238 If (xdont(ndon) > xpiv) Then
4239 icrs = 3
4240 Do
4241 icrs = icrs + 1
4242 If (xdont(icrs) > xpiv) Then
4243 If (icrs >= ndon) Exit
4244 jhig = jhig + 1
4245 xhigt(jhig) = xdont(icrs)
4246 Else
4247 jlow = jlow + 1
4248 xlowt(jlow) = xdont(icrs)
4249 If (jlow >= inth) Exit
4250 End If
4251 End Do
4252 !
4253 ! One restricts further processing because it is no use
4254 ! to store more high values
4255 !
4256 If (icrs < ndon - 1) Then
4257 Do
4258 icrs = icrs + 1
4259 If (xdont(icrs) <= xpiv) Then
4260 jlow = jlow + 1
4261 xlowt(jlow) = xdont(icrs)
4262 Else If (icrs >= ndon) Then
4263 Exit
4264 End If
4265 End Do
4266 End If
4267 !
4268 !
4269 Else
4270 !
4271 ! Same as above, but this is not as easy to optimize, so the
4272 ! DO-loop is kept
4273 !
4274 Do icrs = 4, ndon - 1
4275 If (xdont(icrs) > xpiv) Then
4276 jhig = jhig + 1
4277 xhigt(jhig) = xdont(icrs)
4278 Else
4279 jlow = jlow + 1
4280 xlowt(jlow) = xdont(icrs)
4281 If (jlow >= inth) Exit
4282 End If
4283 End Do
4284 !
4285 If (icrs < ndon - 1) Then
4286 Do
4287 icrs = icrs + 1
4288 If (xdont(icrs) <= xpiv) Then
4289 If (icrs >= ndon) Exit
4290 jlow = jlow + 1
4291 xlowt(jlow) = xdont(icrs)
4292 End If
4293 End Do
4294 End If
4295 End If
4296 !
4297 jlm2 = 0
4298 jlm1 = 0
4299 jhm2 = 0
4300 jhm1 = 0
4301 Do
4302 If (jlm2 == jlow .And. jhm2 == jhig) Then
4303 !
4304 ! We are oscillating. Perturbate by bringing JLOW closer by one
4305 ! to INTH
4306 !
4307 If (inth > jlow) Then
4308 xmin = xhigt(1)
4309 ihig = 1
4310 Do icrs = 2, jhig
4311 If (xhigt(icrs) < xmin) Then
4312 xmin = xhigt(icrs)
4313 ihig = icrs
4314 End If
4315 End Do
4316 !
4317 jlow = jlow + 1
4318 xlowt(jlow) = xhigt(ihig)
4319 xhigt(ihig) = xhigt(jhig)
4320 jhig = jhig - 1
4321 Else
4322
4323 xmax = xlowt(jlow)
4324 jlow = jlow - 1
4325 Do icrs = 1, jlow
4326 If (xlowt(icrs) > xmax) Then
4327 xwrk = xmax
4328 xmax = xlowt(icrs)
4329 xlowt(icrs) = xwrk
4330 End If
4331 End Do
4332 End If
4333 End If
4334 jlm2 = jlm1
4335 jlm1 = jlow
4336 jhm2 = jhm1
4337 jhm1 = jhig
4338 !
4339 ! We try to bring the number of values in the low values set
4340 ! closer to INTH.
4341 !
4342 Select Case (inth - jlow)
4343 Case (2 :)
4344 !
4345 ! Not enough values in low part, at least 2 are missing
4346 !
4347 inth = inth - jlow
4348 jlow = 0
4349 Select Case (jhig)
4350 !!!!! CASE DEFAULT
4351 !!!!! write (unit=*,fmt=*) "Assertion failed"
4352 !!!!! STOP
4353 !
4354 ! We make a special case when we have so few values in
4355 ! the high values set that it is bad performance to choose a pivot
4356 ! and apply the general algorithm.
4357 !
4358 Case (2)
4359 If (xhigt(1) <= xhigt(2)) Then
4360 jlow = jlow + 1
4361 xlowt(jlow) = xhigt(1)
4362 jlow = jlow + 1
4363 xlowt(jlow) = xhigt(2)
4364 Else
4365 jlow = jlow + 1
4366 xlowt(jlow) = xhigt(2)
4367 jlow = jlow + 1
4368 xlowt(jlow) = xhigt(1)
4369 End If
4370 Exit
4371 !
4372 Case (3)
4373 !
4374 !
4375 xwrk1 = xhigt(1)
4376 xwrk2 = xhigt(2)
4377 xwrk3 = xhigt(3)
4378 If (xwrk2 < xwrk1) Then
4379 xhigt(1) = xwrk2
4380 xhigt(2) = xwrk1
4381 xwrk2 = xwrk1
4382 End If
4383 If (xwrk2 > xwrk3) Then
4384 xhigt(3) = xwrk2
4385 xhigt(2) = xwrk3
4386 xwrk2 = xwrk3
4387 If (xwrk2 < xhigt(1)) Then
4388 xhigt(2) = xhigt(1)
4389 xhigt(1) = xwrk2
4390 End If
4391 End If
4392 jhig = 0
4393 Do icrs = jlow + 1, inth
4394 jhig = jhig + 1
4395 xlowt(icrs) = xhigt(jhig)
4396 End Do
4397 jlow = inth
4398 Exit
4399 !
4400 Case (4 :)
4401 !
4402 !
4403 ifin = jhig
4404 !
4405 ! One chooses a pivot from the 2 first values and the last one.
4406 ! This should ensure sufficient renewal between iterations to
4407 ! avoid worst case behavior effects.
4408 !
4409 xwrk1 = xhigt(1)
4410 xwrk2 = xhigt(2)
4411 xwrk3 = xhigt(ifin)
4412 If (xwrk2 < xwrk1) Then
4413 xhigt(1) = xwrk2
4414 xhigt(2) = xwrk1
4415 xwrk2 = xwrk1
4416 End If
4417 If (xwrk2 > xwrk3) Then
4418 xhigt(ifin) = xwrk2
4419 xhigt(2) = xwrk3
4420 xwrk2 = xwrk3
4421 If (xwrk2 < xhigt(1)) Then
4422 xhigt(2) = xhigt(1)
4423 xhigt(1) = xwrk2
4424 End If
4425 End If
4426 !
4427 xwrk1 = xhigt(1)
4428 jlow = jlow + 1
4429 xlowt(jlow) = xwrk1
4430 xpiv = xwrk1 + 0.5 * (xhigt(ifin) - xwrk1)
4431 !
4432 ! One takes values <= pivot to XLOWT
4433 ! Again, 2 parts, one where we take care of the remaining
4434 ! high values because we might still need them, and the
4435 ! other when we know that we will have more than enough
4436 ! low values in the end.
4437 !
4438 jhig = 0
4439 Do icrs = 2, ifin
4440 If (xhigt(icrs) <= xpiv) Then
4441 jlow = jlow + 1
4442 xlowt(jlow) = xhigt(icrs)
4443 If (jlow >= inth) Exit
4444 Else
4445 jhig = jhig + 1
4446 xhigt(jhig) = xhigt(icrs)
4447 End If
4448 End Do
4449 !
4450 Do icrs = icrs + 1, ifin
4451 If (xhigt(icrs) <= xpiv) Then
4452 jlow = jlow + 1
4453 xlowt(jlow) = xhigt(icrs)
4454 End If
4455 End Do
4456 End Select
4457 !
4458 !
4459 Case (1)
4460 !
4461 ! Only 1 value is missing in low part
4462 !
4463 xmin = xhigt(1)
4464 Do icrs = 2, jhig
4465 If (xhigt(icrs) < xmin) Then
4466 xmin = xhigt(icrs)
4467 End If
4468 End Do
4469 !
4470 jlow = jlow + 1
4471 xlowt(jlow) = xmin
4472 Exit
4473 !
4474 !
4475 Case (0)
4476 !
4477 ! Low part is exactly what we want
4478 !
4479 Exit
4480 !
4481 !
4482 Case (-5 : -1)
4483 !
4484 ! Only few values too many in low part
4485 !
4486 IF (ifodd) THEN
4487 jhig = jlow - inth + 1
4488 Else
4489 jhig = jlow - inth + 2
4490 end if
4491 xhigt(1) = xlowt(1)
4492 Do icrs = 2, jhig
4493 xwrk = xlowt(icrs)
4494 Do idcr = icrs - 1, 1, - 1
4495 If (xwrk < xhigt(idcr)) Then
4496 xhigt(idcr + 1) = xhigt(idcr)
4497 Else
4498 Exit
4499 End If
4500 End Do
4501 xhigt(idcr + 1) = xwrk
4502 End Do
4503 !
4504 Do icrs = jhig + 1, jlow
4505 If (xlowt(icrs) > xhigt(1)) Then
4506 xwrk = xlowt(icrs)
4507 Do idcr = 2, jhig
4508 If (xwrk >= xhigt(idcr)) Then
4509 xhigt(idcr - 1) = xhigt(idcr)
4510 else
4511 exit
4512 end if
4513 End Do
4514 xhigt(idcr - 1) = xwrk
4515 End If
4516 End Do
4517 !
4518 IF (ifodd) THEN
4519 median = xhigt(1)
4520 Else
4521 median = 0.5 * (xhigt(1) + xhigt(2))
4522 end if
4523 Return
4524 !
4525 !
4526 Case (: -6)
4527 !
4528 ! last case: too many values in low part
4529 !
4530
4531 imil = (jlow + 1) / 2
4532 ifin = jlow
4533 !
4534 ! One chooses a pivot from 1st, last, and middle values
4535 !
4536 If (xlowt(imil) < xlowt(1)) Then
4537 xwrk = xlowt(1)
4538 xlowt(1) = xlowt(imil)
4539 xlowt(imil) = xwrk
4540 End If
4541 If (xlowt(imil) > xlowt(ifin)) Then
4542 xwrk = xlowt(ifin)
4543 xlowt(ifin) = xlowt(imil)
4544 xlowt(imil) = xwrk
4545 If (xlowt(imil) < xlowt(1)) Then
4546 xwrk = xlowt(1)
4547 xlowt(1) = xlowt(imil)
4548 xlowt(imil) = xwrk
4549 End If
4550 End If
4551 If (ifin <= 3) Exit
4552 !
4553 xpiv = xlowt(1) + real(inth, dp) / real(jlow + inth, dp) * &
4554 (xlowt(ifin) - xlowt(1))
4555
4556 !
4557 ! One takes values > XPIV to XHIGT
4558 !
4559 jhig = 0
4560 jlow = 0
4561 !
4562 If (xlowt(ifin) > xpiv) Then
4563 icrs = 0
4564 Do
4565 icrs = icrs + 1
4566 If (xlowt(icrs) > xpiv) Then
4567 jhig = jhig + 1
4568 xhigt(jhig) = xlowt(icrs)
4569 If (icrs >= ifin) Exit
4570 Else
4571 jlow = jlow + 1
4572 xlowt(jlow) = xlowt(icrs)
4573 If (jlow >= inth) Exit
4574 End If
4575 End Do
4576 !
4577 If (icrs < ifin) Then
4578 Do
4579 icrs = icrs + 1
4580 If (xlowt(icrs) <= xpiv) Then
4581 jlow = jlow + 1
4582 xlowt(jlow) = xlowt(icrs)
4583 Else
4584 If (icrs >= ifin) Exit
4585 End If
4586 End Do
4587 End If
4588 Else
4589 Do icrs = 1, ifin
4590 If (xlowt(icrs) > xpiv) Then
4591 jhig = jhig + 1
4592 xhigt(jhig) = xlowt(icrs)
4593 Else
4594 jlow = jlow + 1
4595 xlowt(jlow) = xlowt(icrs)
4596 If (jlow >= inth) Exit
4597 End If
4598 End Do
4599 !
4600 Do icrs = icrs + 1, ifin
4601 If (xlowt(icrs) <= xpiv) Then
4602 jlow = jlow + 1
4603 xlowt(jlow) = xlowt(icrs)
4604 End If
4605 End Do
4606 End If
4607 !
4608 End Select
4609 !
4610 End Do
4611 !
4612 ! Now, we only need to find maximum of the 1:INTH set
4613 !
4614 if (ifodd) then
4615 median = maxval(xlowt(1 : inth))
4616 else
4617 xwrk = max(xlowt(1), xlowt(2))
4618 xwrk1 = min(xlowt(1), xlowt(2))
4619 DO icrs = 3, inth
4620 IF (xlowt(icrs) > xwrk1) THEN
4621 IF (xlowt(icrs) > xwrk) THEN
4622 xwrk1 = xwrk
4623 xwrk = xlowt(icrs)
4624 Else
4625 xwrk1 = xlowt(icrs)
4626 end if
4627 end if
4628 ENDDO
4629 median = 0.5 * (xwrk + xwrk1)
4630 end if
4631 Return
4632 !
4633 End Function d_median
4634
4635 Function r_median (XDONT) Result (median)
4636 ! Return median value of XDONT
4637 ! __________________________________________________________
4638 ! This routine uses a pivoting strategy such as the one of
4639 ! finding the median based on the quicksort algorithm, but
4640 ! we skew the pivot choice to try to bring it to NORD as
4641 ! fast as possible. It uses 2 temporary arrays, where it
4642 ! stores the indices of the values smaller than the pivot
4643 ! (ILOWT), and the indices of values larger than the pivot
4644 ! that we might still need later on (IHIGT). It iterates
4645 ! until it can bring the number of values in ILOWT to
4646 ! exactly NORD, and then finds the maximum of this set.
4647 ! Michel Olagnon - Aug. 2000
4648 ! __________________________________________________________
4649 ! _________________________________________________________
4650 Real(kind = sp), Dimension (:), Intent (In) :: xdont
4651 Real(kind = sp) :: median
4652 ! __________________________________________________________
4653 Real(kind = sp), Dimension (SIZE(XDONT)) :: xlowt, xhigt
4654 Real(kind = sp) :: xpiv, xwrk, xwrk1, xwrk2, xwrk3, xmin, xmax
4655 !!
4656 Logical :: IFODD
4657 Integer(kind = i4) :: NDON, JHIG, JLOW, IHIG!, NORD
4658 Integer(kind = i4) :: IMIL, IFIN, ICRS, IDCR!, ILOW
4659 Integer(kind = i4) :: JLM2, JLM1, JHM2, JHM1, INTH
4660 !
4661 ndon = SIZE (xdont)
4662 inth = ndon / 2 + 1
4663 ifodd = (2 * inth == ndon + 1)
4664 !
4665 ! First loop is used to fill-in XLOWT, XHIGT at the same time
4666 !
4667 If (ndon < 3) Then
4668 If (ndon > 0) median = 0.5 * (xdont(1) + xdont(ndon))
4669 Return
4670 End If
4671 !
4672 ! One chooses a pivot, best estimate possible to put fractile near
4673 ! mid-point of the set of low values.
4674 !
4675 If (xdont(2) < xdont(1)) Then
4676 xlowt(1) = xdont(2)
4677 xhigt(1) = xdont(1)
4678 Else
4679 xlowt(1) = xdont(1)
4680 xhigt(1) = xdont(2)
4681 End If
4682 !
4683 !
4684 If (xdont(3) < xhigt(1)) Then
4685 xhigt(2) = xhigt(1)
4686 If (xdont(3) < xlowt(1)) Then
4687 xhigt(1) = xlowt(1)
4688 xlowt(1) = xdont(3)
4689 Else
4690 xhigt(1) = xdont(3)
4691 End If
4692 Else
4693 xhigt(2) = xdont(3)
4694 End If
4695 !
4696 If (ndon < 4) Then ! 3 values
4697 median = xhigt(1)
4698 Return
4699 End If
4700 !
4701 If (xdont(ndon) < xhigt(1)) Then
4702 xhigt(3) = xhigt(2)
4703 xhigt(2) = xhigt(1)
4704 If (xdont(ndon) < xlowt(1)) Then
4705 xhigt(1) = xlowt(1)
4706 xlowt(1) = xdont(ndon)
4707 Else
4708 xhigt(1) = xdont(ndon)
4709 End If
4710 Else
4711 If (xdont(ndon) < xhigt(2)) Then
4712 xhigt(3) = xhigt(2)
4713 xhigt(2) = xdont(ndon)
4714 Else
4715 xhigt(3) = xdont(ndon)
4716 End If
4717 End If
4718 !
4719 If (ndon < 5) Then ! 4 values
4720 median = 0.5 * (xhigt(1) + xhigt(2))
4721 Return
4722 End If
4723 !
4724 jlow = 1
4725 jhig = 3
4726 xpiv = xlowt(1) + 2.0 * (xhigt(3) - xlowt(1)) / 3.0
4727 If (xpiv >= xhigt(1)) Then
4728 xpiv = xlowt(1) + 2.0 * (xhigt(2) - xlowt(1)) / 3.0
4729 If (xpiv >= xhigt(1)) xpiv = xlowt(1) + 2.0 * (xhigt(1) - xlowt(1)) / 3.0
4730 End If
4731 !
4732 ! One puts values > pivot in the end and those <= pivot
4733 ! at the beginning. This is split in 2 cases, so that
4734 ! we can skip the loop test a number of times.
4735 ! As we are also filling in the work arrays at the same time
4736 ! we stop filling in the XHIGT array as soon as we have more
4737 ! than enough values in XLOWT.
4738 !
4739 !
4740 If (xdont(ndon) > xpiv) Then
4741 icrs = 3
4742 Do
4743 icrs = icrs + 1
4744 If (xdont(icrs) > xpiv) Then
4745 If (icrs >= ndon) Exit
4746 jhig = jhig + 1
4747 xhigt(jhig) = xdont(icrs)
4748 Else
4749 jlow = jlow + 1
4750 xlowt(jlow) = xdont(icrs)
4751 If (jlow >= inth) Exit
4752 End If
4753 End Do
4754 !
4755 ! One restricts further processing because it is no use
4756 ! to store more high values
4757 !
4758 If (icrs < ndon - 1) Then
4759 Do
4760 icrs = icrs + 1
4761 If (xdont(icrs) <= xpiv) Then
4762 jlow = jlow + 1
4763 xlowt(jlow) = xdont(icrs)
4764 Else If (icrs >= ndon) Then
4765 Exit
4766 End If
4767 End Do
4768 End If
4769 !
4770 !
4771 Else
4772 !
4773 ! Same as above, but this is not as easy to optimize, so the
4774 ! DO-loop is kept
4775 !
4776 Do icrs = 4, ndon - 1
4777 If (xdont(icrs) > xpiv) Then
4778 jhig = jhig + 1
4779 xhigt(jhig) = xdont(icrs)
4780 Else
4781 jlow = jlow + 1
4782 xlowt(jlow) = xdont(icrs)
4783 If (jlow >= inth) Exit
4784 End If
4785 End Do
4786 !
4787 If (icrs < ndon - 1) Then
4788 Do
4789 icrs = icrs + 1
4790 If (xdont(icrs) <= xpiv) Then
4791 If (icrs >= ndon) Exit
4792 jlow = jlow + 1
4793 xlowt(jlow) = xdont(icrs)
4794 End If
4795 End Do
4796 End If
4797 End If
4798 !
4799 jlm2 = 0
4800 jlm1 = 0
4801 jhm2 = 0
4802 jhm1 = 0
4803 Do
4804 If (jlm2 == jlow .And. jhm2 == jhig) Then
4805 !
4806 ! We are oscillating. Perturbate by bringing JLOW closer by one
4807 ! to INTH
4808 !
4809 If (inth > jlow) Then
4810 xmin = xhigt(1)
4811 ihig = 1
4812 Do icrs = 2, jhig
4813 If (xhigt(icrs) < xmin) Then
4814 xmin = xhigt(icrs)
4815 ihig = icrs
4816 End If
4817 End Do
4818 !
4819 jlow = jlow + 1
4820 xlowt(jlow) = xhigt(ihig)
4821 xhigt(ihig) = xhigt(jhig)
4822 jhig = jhig - 1
4823 Else
4824
4825 xmax = xlowt(jlow)
4826 jlow = jlow - 1
4827 Do icrs = 1, jlow
4828 If (xlowt(icrs) > xmax) Then
4829 xwrk = xmax
4830 xmax = xlowt(icrs)
4831 xlowt(icrs) = xwrk
4832 End If
4833 End Do
4834 End If
4835 End If
4836 jlm2 = jlm1
4837 jlm1 = jlow
4838 jhm2 = jhm1
4839 jhm1 = jhig
4840 !
4841 ! We try to bring the number of values in the low values set
4842 ! closer to INTH.
4843 !
4844 Select Case (inth - jlow)
4845 Case (2 :)
4846 !
4847 ! Not enough values in low part, at least 2 are missing
4848 !
4849 inth = inth - jlow
4850 jlow = 0
4851 Select Case (jhig)
4852 !!!!! CASE DEFAULT
4853 !!!!! write (unit=*,fmt=*) "Assertion failed"
4854 !!!!! STOP
4855 !
4856 ! We make a special case when we have so few values in
4857 ! the high values set that it is bad performance to choose a pivot
4858 ! and apply the general algorithm.
4859 !
4860 Case (2)
4861 If (xhigt(1) <= xhigt(2)) Then
4862 jlow = jlow + 1
4863 xlowt(jlow) = xhigt(1)
4864 jlow = jlow + 1
4865 xlowt(jlow) = xhigt(2)
4866 Else
4867 jlow = jlow + 1
4868 xlowt(jlow) = xhigt(2)
4869 jlow = jlow + 1
4870 xlowt(jlow) = xhigt(1)
4871 End If
4872 Exit
4873 !
4874 Case (3)
4875 !
4876 !
4877 xwrk1 = xhigt(1)
4878 xwrk2 = xhigt(2)
4879 xwrk3 = xhigt(3)
4880 If (xwrk2 < xwrk1) Then
4881 xhigt(1) = xwrk2
4882 xhigt(2) = xwrk1
4883 xwrk2 = xwrk1
4884 End If
4885 If (xwrk2 > xwrk3) Then
4886 xhigt(3) = xwrk2
4887 xhigt(2) = xwrk3
4888 xwrk2 = xwrk3
4889 If (xwrk2 < xhigt(1)) Then
4890 xhigt(2) = xhigt(1)
4891 xhigt(1) = xwrk2
4892 End If
4893 End If
4894 jhig = 0
4895 Do icrs = jlow + 1, inth
4896 jhig = jhig + 1
4897 xlowt(icrs) = xhigt(jhig)
4898 End Do
4899 jlow = inth
4900 Exit
4901 !
4902 Case (4 :)
4903 !
4904 !
4905 ifin = jhig
4906 !
4907 ! One chooses a pivot from the 2 first values and the last one.
4908 ! This should ensure sufficient renewal between iterations to
4909 ! avoid worst case behavior effects.
4910 !
4911 xwrk1 = xhigt(1)
4912 xwrk2 = xhigt(2)
4913 xwrk3 = xhigt(ifin)
4914 If (xwrk2 < xwrk1) Then
4915 xhigt(1) = xwrk2
4916 xhigt(2) = xwrk1
4917 xwrk2 = xwrk1
4918 End If
4919 If (xwrk2 > xwrk3) Then
4920 xhigt(ifin) = xwrk2
4921 xhigt(2) = xwrk3
4922 xwrk2 = xwrk3
4923 If (xwrk2 < xhigt(1)) Then
4924 xhigt(2) = xhigt(1)
4925 xhigt(1) = xwrk2
4926 End If
4927 End If
4928 !
4929 xwrk1 = xhigt(1)
4930 jlow = jlow + 1
4931 xlowt(jlow) = xwrk1
4932 xpiv = xwrk1 + 0.5 * (xhigt(ifin) - xwrk1)
4933 !
4934 ! One takes values <= pivot to XLOWT
4935 ! Again, 2 parts, one where we take care of the remaining
4936 ! high values because we might still need them, and the
4937 ! other when we know that we will have more than enough
4938 ! low values in the end.
4939 !
4940 jhig = 0
4941 Do icrs = 2, ifin
4942 If (xhigt(icrs) <= xpiv) Then
4943 jlow = jlow + 1
4944 xlowt(jlow) = xhigt(icrs)
4945 If (jlow >= inth) Exit
4946 Else
4947 jhig = jhig + 1
4948 xhigt(jhig) = xhigt(icrs)
4949 End If
4950 End Do
4951 !
4952 Do icrs = icrs + 1, ifin
4953 If (xhigt(icrs) <= xpiv) Then
4954 jlow = jlow + 1
4955 xlowt(jlow) = xhigt(icrs)
4956 End If
4957 End Do
4958 End Select
4959 !
4960 !
4961 Case (1)
4962 !
4963 ! Only 1 value is missing in low part
4964 !
4965 xmin = xhigt(1)
4966 Do icrs = 2, jhig
4967 If (xhigt(icrs) < xmin) Then
4968 xmin = xhigt(icrs)
4969 End If
4970 End Do
4971 !
4972 jlow = jlow + 1
4973 xlowt(jlow) = xmin
4974 Exit
4975 !
4976 !
4977 Case (0)
4978 !
4979 ! Low part is exactly what we want
4980 !
4981 Exit
4982 !
4983 !
4984 Case (-5 : -1)
4985 !
4986 ! Only few values too many in low part
4987 !
4988 IF (ifodd) THEN
4989 jhig = jlow - inth + 1
4990 Else
4991 jhig = jlow - inth + 2
4992 end if
4993 xhigt(1) = xlowt(1)
4994 Do icrs = 2, jhig
4995 xwrk = xlowt(icrs)
4996 Do idcr = icrs - 1, 1, - 1
4997 If (xwrk < xhigt(idcr)) Then
4998 xhigt(idcr + 1) = xhigt(idcr)
4999 Else
5000 Exit
5001 End If
5002 End Do
5003 xhigt(idcr + 1) = xwrk
5004 End Do
5005 !
5006 Do icrs = jhig + 1, jlow
5007 If (xlowt(icrs) > xhigt(1)) Then
5008 xwrk = xlowt(icrs)
5009 Do idcr = 2, jhig
5010 If (xwrk >= xhigt(idcr)) Then
5011 xhigt(idcr - 1) = xhigt(idcr)
5012 else
5013 exit
5014 end if
5015 End Do
5016 xhigt(idcr - 1) = xwrk
5017 End If
5018 End Do
5019 !
5020 IF (ifodd) THEN
5021 median = xhigt(1)
5022 Else
5023 median = 0.5 * (xhigt(1) + xhigt(2))
5024 end if
5025 Return
5026 !
5027 !
5028 Case (: -6)
5029 !
5030 ! last case: too many values in low part
5031 !
5032
5033 imil = (jlow + 1) / 2
5034 ifin = jlow
5035 !
5036 ! One chooses a pivot from 1st, last, and middle values
5037 !
5038 If (xlowt(imil) < xlowt(1)) Then
5039 xwrk = xlowt(1)
5040 xlowt(1) = xlowt(imil)
5041 xlowt(imil) = xwrk
5042 End If
5043 If (xlowt(imil) > xlowt(ifin)) Then
5044 xwrk = xlowt(ifin)
5045 xlowt(ifin) = xlowt(imil)
5046 xlowt(imil) = xwrk
5047 If (xlowt(imil) < xlowt(1)) Then
5048 xwrk = xlowt(1)
5049 xlowt(1) = xlowt(imil)
5050 xlowt(imil) = xwrk
5051 End If
5052 End If
5053 If (ifin <= 3) Exit
5054 !
5055 xpiv = xlowt(1) + real(inth, sp) / real(jlow + inth, sp) * &
5056 (xlowt(ifin) - xlowt(1))
5057
5058 !
5059 ! One takes values > XPIV to XHIGT
5060 !
5061 jhig = 0
5062 jlow = 0
5063 !
5064 If (xlowt(ifin) > xpiv) Then
5065 icrs = 0
5066 Do
5067 icrs = icrs + 1
5068 If (xlowt(icrs) > xpiv) Then
5069 jhig = jhig + 1
5070 xhigt(jhig) = xlowt(icrs)
5071 If (icrs >= ifin) Exit
5072 Else
5073 jlow = jlow + 1
5074 xlowt(jlow) = xlowt(icrs)
5075 If (jlow >= inth) Exit
5076 End If
5077 End Do
5078 !
5079 If (icrs < ifin) Then
5080 Do
5081 icrs = icrs + 1
5082 If (xlowt(icrs) <= xpiv) Then
5083 jlow = jlow + 1
5084 xlowt(jlow) = xlowt(icrs)
5085 Else
5086 If (icrs >= ifin) Exit
5087 End If
5088 End Do
5089 End If
5090 Else
5091 Do icrs = 1, ifin
5092 If (xlowt(icrs) > xpiv) Then
5093 jhig = jhig + 1
5094 xhigt(jhig) = xlowt(icrs)
5095 Else
5096 jlow = jlow + 1
5097 xlowt(jlow) = xlowt(icrs)
5098 If (jlow >= inth) Exit
5099 End If
5100 End Do
5101 !
5102 Do icrs = icrs + 1, ifin
5103 If (xlowt(icrs) <= xpiv) Then
5104 jlow = jlow + 1
5105 xlowt(jlow) = xlowt(icrs)
5106 End If
5107 End Do
5108 End If
5109 !
5110 End Select
5111 !
5112 End Do
5113 !
5114 ! Now, we only need to find maximum of the 1:INTH set
5115 !
5116 if (ifodd) then
5117 median = maxval(xlowt(1 : inth))
5118 else
5119 xwrk = max(xlowt(1), xlowt(2))
5120 xwrk1 = min(xlowt(1), xlowt(2))
5121 DO icrs = 3, inth
5122 IF (xlowt(icrs) > xwrk1) THEN
5123 IF (xlowt(icrs) > xwrk) THEN
5124 xwrk1 = xwrk
5125 xwrk = xlowt(icrs)
5126 Else
5127 xwrk1 = xlowt(icrs)
5128 end if
5129 end if
5130 ENDDO
5131 median = 0.5 * (xwrk + xwrk1)
5132 end if
5133 Return
5134 !
5135 End Function r_median
5136
5137 Function i_median (XDONT) Result (median)
5138 ! Return median value of XDONT
5139 ! __________________________________________________________
5140 ! This routine uses a pivoting strategy such as the one of
5141 ! finding the median based on the quicksort algorithm, but
5142 ! we skew the pivot choice to try to bring it to NORD as
5143 ! fast as possible. It uses 2 temporary arrays, where it
5144 ! stores the indices of the values smaller than the pivot
5145 ! (ILOWT), and the indices of values larger than the pivot
5146 ! that we might still need later on (IHIGT). It iterates
5147 ! until it can bring the number of values in ILOWT to
5148 ! exactly NORD, and then finds the maximum of this set.
5149 ! Michel Olagnon - Aug. 2000
5150 ! __________________________________________________________
5151 ! __________________________________________________________
5152 Integer(kind = i4), Dimension (:), Intent (In) :: XDONT
5153 Integer(kind = i4) :: median
5154 ! __________________________________________________________
5155 Integer(kind = i4), Dimension (SIZE(XDONT)) :: XLOWT, XHIGT
5156 Integer(kind = i4) :: XPIV, XWRK, XWRK1, XWRK2, XWRK3, XMIN, XMAX
5157 !!
5158 Logical :: IFODD
5159 Integer(kind = i4) :: NDON, JHIG, JLOW, IHIG!, NORD
5160 Integer(kind = i4) :: IMIL, IFIN, ICRS, IDCR!, ILOW
5161 Integer(kind = i4) :: JLM2, JLM1, JHM2, JHM1, INTH
5162 !
5163 ndon = SIZE (xdont)
5164 inth = ndon / 2 + 1
5165 ifodd = (2 * inth == ndon + 1)
5166 !
5167 ! First loop is used to fill-in XLOWT, XHIGT at the same time
5168 !
5169 If (ndon < 3) Then
5170 If (ndon > 0) median = (xdont(1) + xdont(ndon)) / 2
5171 Return
5172 End If
5173 !
5174 ! One chooses a pivot, best estimate possible to put fractile near
5175 ! mid-point of the set of low values.
5176 !
5177 If (xdont(2) < xdont(1)) Then
5178 xlowt(1) = xdont(2)
5179 xhigt(1) = xdont(1)
5180 Else
5181 xlowt(1) = xdont(1)
5182 xhigt(1) = xdont(2)
5183 End If
5184 !
5185 !
5186 If (xdont(3) < xhigt(1)) Then
5187 xhigt(2) = xhigt(1)
5188 If (xdont(3) < xlowt(1)) Then
5189 xhigt(1) = xlowt(1)
5190 xlowt(1) = xdont(3)
5191 Else
5192 xhigt(1) = xdont(3)
5193 End If
5194 Else
5195 xhigt(2) = xdont(3)
5196 End If
5197 !
5198 If (ndon < 4) Then ! 3 values
5199 median = xhigt(1)
5200 Return
5201 End If
5202 !
5203 If (xdont(ndon) < xhigt(1)) Then
5204 xhigt(3) = xhigt(2)
5205 xhigt(2) = xhigt(1)
5206 If (xdont(ndon) < xlowt(1)) Then
5207 xhigt(1) = xlowt(1)
5208 xlowt(1) = xdont(ndon)
5209 Else
5210 xhigt(1) = xdont(ndon)
5211 End If
5212 Else
5213 If (xdont(ndon) < xhigt(2)) Then
5214 xhigt(3) = xhigt(2)
5215 xhigt(2) = xdont(ndon)
5216 Else
5217 xhigt(3) = xdont(ndon)
5218 End If
5219 End If
5220 !
5221 If (ndon < 5) Then ! 4 values
5222 median = (xhigt(1) + xhigt(2)) / 2
5223 Return
5224 End If
5225 !
5226 jlow = 1
5227 jhig = 3
5228 xpiv = xlowt(1) + 2 * (xhigt(3) - xlowt(1)) / 3
5229 If (xpiv >= xhigt(1)) Then
5230 xpiv = xlowt(1) + 2 * (xhigt(2) - xlowt(1)) / 3
5231 If (xpiv >= xhigt(1)) xpiv = xlowt(1) + 2 * (xhigt(1) - xlowt(1)) / 3
5232 End If
5233 !
5234 ! One puts values > pivot in the end and those <= pivot
5235 ! at the beginning. This is split in 2 cases, so that
5236 ! we can skip the loop test a number of times.
5237 ! As we are also filling in the work arrays at the same time
5238 ! we stop filling in the XHIGT array as soon as we have more
5239 ! than enough values in XLOWT.
5240 !
5241 !
5242 If (xdont(ndon) > xpiv) Then
5243 icrs = 3
5244 Do
5245 icrs = icrs + 1
5246 If (xdont(icrs) > xpiv) Then
5247 If (icrs >= ndon) Exit
5248 jhig = jhig + 1
5249 xhigt(jhig) = xdont(icrs)
5250 Else
5251 jlow = jlow + 1
5252 xlowt(jlow) = xdont(icrs)
5253 If (jlow >= inth) Exit
5254 End If
5255 End Do
5256 !
5257 ! One restricts further processing because it is no use
5258 ! to store more high values
5259 !
5260 If (icrs < ndon - 1) Then
5261 Do
5262 icrs = icrs + 1
5263 If (xdont(icrs) <= xpiv) Then
5264 jlow = jlow + 1
5265 xlowt(jlow) = xdont(icrs)
5266 Else If (icrs >= ndon) Then
5267 Exit
5268 End If
5269 End Do
5270 End If
5271 !
5272 !
5273 Else
5274 !
5275 ! Same as above, but this is not as easy to optimize, so the
5276 ! DO-loop is kept
5277 !
5278 Do icrs = 4, ndon - 1
5279 If (xdont(icrs) > xpiv) Then
5280 jhig = jhig + 1
5281 xhigt(jhig) = xdont(icrs)
5282 Else
5283 jlow = jlow + 1
5284 xlowt(jlow) = xdont(icrs)
5285 If (jlow >= inth) Exit
5286 End If
5287 End Do
5288 !
5289 If (icrs < ndon - 1) Then
5290 Do
5291 icrs = icrs + 1
5292 If (xdont(icrs) <= xpiv) Then
5293 If (icrs >= ndon) Exit
5294 jlow = jlow + 1
5295 xlowt(jlow) = xdont(icrs)
5296 End If
5297 End Do
5298 End If
5299 End If
5300 !
5301 jlm2 = 0
5302 jlm1 = 0
5303 jhm2 = 0
5304 jhm1 = 0
5305 Do
5306 If (jlm2 == jlow .And. jhm2 == jhig) Then
5307 !
5308 ! We are oscillating. Perturbate by bringing JLOW closer by one
5309 ! to INTH
5310 !
5311 If (inth > jlow) Then
5312 xmin = xhigt(1)
5313 ihig = 1
5314 Do icrs = 2, jhig
5315 If (xhigt(icrs) < xmin) Then
5316 xmin = xhigt(icrs)
5317 ihig = icrs
5318 End If
5319 End Do
5320 !
5321 jlow = jlow + 1
5322 xlowt(jlow) = xhigt(ihig)
5323 xhigt(ihig) = xhigt(jhig)
5324 jhig = jhig - 1
5325 Else
5326
5327 xmax = xlowt(jlow)
5328 jlow = jlow - 1
5329 Do icrs = 1, jlow
5330 If (xlowt(icrs) > xmax) Then
5331 xwrk = xmax
5332 xmax = xlowt(icrs)
5333 xlowt(icrs) = xwrk
5334 End If
5335 End Do
5336 End If
5337 End If
5338 jlm2 = jlm1
5339 jlm1 = jlow
5340 jhm2 = jhm1
5341 jhm1 = jhig
5342 !
5343 ! We try to bring the number of values in the low values set
5344 ! closer to INTH.
5345 !
5346 Select Case (inth - jlow)
5347 Case (2 :)
5348 !
5349 ! Not enough values in low part, at least 2 are missing
5350 !
5351 inth = inth - jlow
5352 jlow = 0
5353 Select Case (jhig)
5354 !!!!! CASE DEFAULT
5355 !!!!! write (unit=*,fmt=*) "Assertion failed"
5356 !!!!! STOP
5357 !
5358 ! We make a special case when we have so few values in
5359 ! the high values set that it is bad performance to choose a pivot
5360 ! and apply the general algorithm.
5361 !
5362 Case (2)
5363 If (xhigt(1) <= xhigt(2)) Then
5364 jlow = jlow + 1
5365 xlowt(jlow) = xhigt(1)
5366 jlow = jlow + 1
5367 xlowt(jlow) = xhigt(2)
5368 Else
5369 jlow = jlow + 1
5370 xlowt(jlow) = xhigt(2)
5371 jlow = jlow + 1
5372 xlowt(jlow) = xhigt(1)
5373 End If
5374 Exit
5375 !
5376 Case (3)
5377 !
5378 !
5379 xwrk1 = xhigt(1)
5380 xwrk2 = xhigt(2)
5381 xwrk3 = xhigt(3)
5382 If (xwrk2 < xwrk1) Then
5383 xhigt(1) = xwrk2
5384 xhigt(2) = xwrk1
5385 xwrk2 = xwrk1
5386 End If
5387 If (xwrk2 > xwrk3) Then
5388 xhigt(3) = xwrk2
5389 xhigt(2) = xwrk3
5390 xwrk2 = xwrk3
5391 If (xwrk2 < xhigt(1)) Then
5392 xhigt(2) = xhigt(1)
5393 xhigt(1) = xwrk2
5394 End If
5395 End If
5396 jhig = 0
5397 Do icrs = jlow + 1, inth
5398 jhig = jhig + 1
5399 xlowt(icrs) = xhigt(jhig)
5400 End Do
5401 jlow = inth
5402 Exit
5403 !
5404 Case (4 :)
5405 !
5406 !
5407 ifin = jhig
5408 !
5409 ! One chooses a pivot from the 2 first values and the last one.
5410 ! This should ensure sufficient renewal between iterations to
5411 ! avoid worst case behavior effects.
5412 !
5413 xwrk1 = xhigt(1)
5414 xwrk2 = xhigt(2)
5415 xwrk3 = xhigt(ifin)
5416 If (xwrk2 < xwrk1) Then
5417 xhigt(1) = xwrk2
5418 xhigt(2) = xwrk1
5419 xwrk2 = xwrk1
5420 End If
5421 If (xwrk2 > xwrk3) Then
5422 xhigt(ifin) = xwrk2
5423 xhigt(2) = xwrk3
5424 xwrk2 = xwrk3
5425 If (xwrk2 < xhigt(1)) Then
5426 xhigt(2) = xhigt(1)
5427 xhigt(1) = xwrk2
5428 End If
5429 End If
5430 !
5431 xwrk1 = xhigt(1)
5432 jlow = jlow + 1
5433 xlowt(jlow) = xwrk1
5434 xpiv = xwrk1 + (xhigt(ifin) - xwrk1) / 2
5435 !
5436 ! One takes values <= pivot to XLOWT
5437 ! Again, 2 parts, one where we take care of the remaining
5438 ! high values because we might still need them, and the
5439 ! other when we know that we will have more than enough
5440 ! low values in the end.
5441 !
5442 jhig = 0
5443 Do icrs = 2, ifin
5444 If (xhigt(icrs) <= xpiv) Then
5445 jlow = jlow + 1
5446 xlowt(jlow) = xhigt(icrs)
5447 If (jlow >= inth) Exit
5448 Else
5449 jhig = jhig + 1
5450 xhigt(jhig) = xhigt(icrs)
5451 End If
5452 End Do
5453 !
5454 Do icrs = icrs + 1, ifin
5455 If (xhigt(icrs) <= xpiv) Then
5456 jlow = jlow + 1
5457 xlowt(jlow) = xhigt(icrs)
5458 End If
5459 End Do
5460 End Select
5461 !
5462 !
5463 Case (1)
5464 !
5465 ! Only 1 value is missing in low part
5466 !
5467 xmin = xhigt(1)
5468 Do icrs = 2, jhig
5469 If (xhigt(icrs) < xmin) Then
5470 xmin = xhigt(icrs)
5471 End If
5472 End Do
5473 !
5474 jlow = jlow + 1
5475 xlowt(jlow) = xmin
5476 Exit
5477 !
5478 !
5479 Case (0)
5480 !
5481 ! Low part is exactly what we want
5482 !
5483 Exit
5484 !
5485 !
5486 Case (-5 : -1)
5487 !
5488 ! Only few values too many in low part
5489 !
5490 IF (ifodd) THEN
5491 jhig = jlow - inth + 1
5492 Else
5493 jhig = jlow - inth + 2
5494 end if
5495 xhigt(1) = xlowt(1)
5496 Do icrs = 2, jhig
5497 xwrk = xlowt(icrs)
5498 Do idcr = icrs - 1, 1, - 1
5499 If (xwrk < xhigt(idcr)) Then
5500 xhigt(idcr + 1) = xhigt(idcr)
5501 Else
5502 Exit
5503 End If
5504 End Do
5505 xhigt(idcr + 1) = xwrk
5506 End Do
5507 !
5508 Do icrs = jhig + 1, jlow
5509 If (xlowt(icrs) > xhigt(1)) Then
5510 xwrk = xlowt(icrs)
5511 Do idcr = 2, jhig
5512 If (xwrk >= xhigt(idcr)) Then
5513 xhigt(idcr - 1) = xhigt(idcr)
5514 else
5515 exit
5516 end if
5517 End Do
5518 xhigt(idcr - 1) = xwrk
5519 End If
5520 End Do
5521 !
5522 IF (ifodd) THEN
5523 median = xhigt(1)
5524 Else
5525 median = (xhigt(1) + xhigt(2)) / 2
5526 end if
5527 Return
5528 !
5529 !
5530 Case (: -6)
5531 !
5532 ! last case: too many values in low part
5533 !
5534
5535 imil = (jlow + 1) / 2
5536 ifin = jlow
5537 !
5538 ! One chooses a pivot from 1st, last, and middle values
5539 !
5540 If (xlowt(imil) < xlowt(1)) Then
5541 xwrk = xlowt(1)
5542 xlowt(1) = xlowt(imil)
5543 xlowt(imil) = xwrk
5544 End If
5545 If (xlowt(imil) > xlowt(ifin)) Then
5546 xwrk = xlowt(ifin)
5547 xlowt(ifin) = xlowt(imil)
5548 xlowt(imil) = xwrk
5549 If (xlowt(imil) < xlowt(1)) Then
5550 xwrk = xlowt(1)
5551 xlowt(1) = xlowt(imil)
5552 xlowt(imil) = xwrk
5553 End If
5554 End If
5555 If (ifin <= 3) Exit
5556 !
5557 xpiv = xlowt(1) + int(real(inth, sp) / real(jlow + inth, sp), i4) * &
5558 (xlowt(ifin) - xlowt(1))
5559
5560 !
5561 ! One takes values > XPIV to XHIGT
5562 !
5563 jhig = 0
5564 jlow = 0
5565 !
5566 If (xlowt(ifin) > xpiv) Then
5567 icrs = 0
5568 Do
5569 icrs = icrs + 1
5570 If (xlowt(icrs) > xpiv) Then
5571 jhig = jhig + 1
5572 xhigt(jhig) = xlowt(icrs)
5573 If (icrs >= ifin) Exit
5574 Else
5575 jlow = jlow + 1
5576 xlowt(jlow) = xlowt(icrs)
5577 If (jlow >= inth) Exit
5578 End If
5579 End Do
5580 !
5581 If (icrs < ifin) Then
5582 Do
5583 icrs = icrs + 1
5584 If (xlowt(icrs) <= xpiv) Then
5585 jlow = jlow + 1
5586 xlowt(jlow) = xlowt(icrs)
5587 Else
5588 If (icrs >= ifin) Exit
5589 End If
5590 End Do
5591 End If
5592 Else
5593 Do icrs = 1, ifin
5594 If (xlowt(icrs) > xpiv) Then
5595 jhig = jhig + 1
5596 xhigt(jhig) = xlowt(icrs)
5597 Else
5598 jlow = jlow + 1
5599 xlowt(jlow) = xlowt(icrs)
5600 If (jlow >= inth) Exit
5601 End If
5602 End Do
5603 !
5604 Do icrs = icrs + 1, ifin
5605 If (xlowt(icrs) <= xpiv) Then
5606 jlow = jlow + 1
5607 xlowt(jlow) = xlowt(icrs)
5608 End If
5609 End Do
5610 End If
5611 !
5612 End Select
5613 !
5614 End Do
5615 !
5616 ! Now, we only need to find maximum of the 1:INTH set
5617 !
5618 if (ifodd) then
5619 median = maxval(xlowt(1 : inth))
5620 else
5621 xwrk = max(xlowt(1), xlowt(2))
5622 xwrk1 = min(xlowt(1), xlowt(2))
5623 DO icrs = 3, inth
5624 IF (xlowt(icrs) > xwrk1) THEN
5625 IF (xlowt(icrs) > xwrk) THEN
5626 xwrk1 = xwrk
5627 xwrk = xlowt(icrs)
5628 Else
5629 xwrk1 = xlowt(icrs)
5630 end if
5631 end if
5632 ENDDO
5633 median = (xwrk + xwrk1) / 2
5634 end if
5635 Return
5636 !
5637 End Function i_median
5638
5639 Subroutine d_mrgref (XVALT, IRNGT)
5640 ! Ranks array XVALT into index array IRNGT, using merge-sort
5641 ! __________________________________________________________
5642 ! This version is not optimized for performance, and is thus
5643 ! not as difficult to read as some other ones.
5644 ! Michel Olagnon - April 2000
5645 ! __________________________________________________________
5646 ! __________________________________________________________
5647 real(kind = dp), Dimension (:), Intent (In) :: xvalt
5648 Integer(kind = i4), Dimension (:), Intent (Out) :: IRNGT
5649 ! __________________________________________________________
5650 !
5651 Integer(kind = i4), Dimension (:), Allocatable :: JWRKT
5652 Integer(kind = i4) :: LMTNA, LMTNC
5653 Integer(kind = i4) :: NVAL, IIND, IWRKD, IWRK, IWRKF, JINDA, IINDA, IINDB
5654 !
5655 nval = min(SIZE(xvalt), SIZE(irngt))
5656 If (nval <= 0) Then
5657 Return
5658 End If
5659 !
5660 ! Fill-in the index array, creating ordered couples
5661 !
5662 Do iind = 2, nval, 2
5663 If (xvalt(iind - 1) <= xvalt(iind)) Then
5664 irngt(iind - 1) = iind - 1
5665 irngt(iind) = iind
5666 Else
5667 irngt(iind - 1) = iind
5668 irngt(iind) = iind - 1
5669 End If
5670 End Do
5671 If (modulo(nval, 2) /= 0) Then
5672 irngt(nval) = nval
5673 End If
5674 !
5675 ! We will now have ordered subsets A - B - A - B - ...
5676 ! and merge A and B couples into C - C - ...
5677 !
5678 Allocate (jwrkt(1 : nval))
5679 lmtnc = 2
5680 lmtna = 2
5681 !
5682 ! Iteration. Each time, the length of the ordered subsets
5683 ! is doubled.
5684 !
5685 Do
5686 If (lmtna >= nval) Exit
5687 iwrkf = 0
5688 lmtnc = 2 * lmtnc
5689 iwrk = 0
5690 !
5691 ! Loop on merges of A and B into C
5692 !
5693 Do
5694 iinda = iwrkf
5695 iwrkd = iwrkf + 1
5696 iwrkf = iinda + lmtnc
5697 jinda = iinda + lmtna
5698 If (iwrkf >= nval) Then
5699 If (jinda >= nval) Exit
5700 iwrkf = nval
5701 End If
5702 iindb = jinda
5703 !
5704 ! Shortcut for the case when the max of A is smaller
5705 ! than the min of B (no need to do anything)
5706 !
5707 If (xvalt(irngt(jinda)) <= xvalt(irngt(jinda + 1))) Then
5708 iwrk = iwrkf
5709 cycle
5710 End If
5711 !
5712 ! One steps in the C subset, that we create in the final rank array
5713 !
5714 Do
5715 If (iwrk >= iwrkf) Then
5716 !
5717 ! Make a copy of the rank array for next iteration
5718 !
5719 irngt(iwrkd : iwrkf) = jwrkt(iwrkd : iwrkf)
5720 Exit
5721 End If
5722 !
5723 iwrk = iwrk + 1
5724 !
5725 ! We still have unprocessed values in both A and B
5726 !
5727 If (iinda < jinda) Then
5728 If (iindb < iwrkf) Then
5729 If (xvalt(irngt(iinda + 1)) > xvalt(irngt(iindb + 1))) &
5730 & Then
5731 iindb = iindb + 1
5732 jwrkt(iwrk) = irngt(iindb)
5733 Else
5734 iinda = iinda + 1
5735 jwrkt(iwrk) = irngt(iinda)
5736 End If
5737 Else
5738 !
5739 ! Only A still with unprocessed values
5740 !
5741 iinda = iinda + 1
5742 jwrkt(iwrk) = irngt(iinda)
5743 End If
5744 Else
5745 !
5746 ! Only B still with unprocessed values
5747 !
5748 irngt(iwrkd : iindb) = jwrkt(iwrkd : iindb)
5749 iwrk = iwrkf
5750 Exit
5751 End If
5752 !
5753 End Do
5754 End Do
5755 !
5756 ! The Cs become As and Bs
5757 !
5758 lmtna = 2 * lmtna
5759 End Do
5760 !
5761 ! Clean up
5762 !
5763 Deallocate (jwrkt)
5764 Return
5765 !
5766 End Subroutine d_mrgref
5767
5768 Subroutine r_mrgref (XVALT, IRNGT)
5769 ! Ranks array XVALT into index array IRNGT, using merge-sort
5770 ! __________________________________________________________
5771 ! This version is not optimized for performance, and is thus
5772 ! not as difficult to read as some other ones.
5773 ! Michel Olagnon - April 2000
5774 ! __________________________________________________________
5775 ! _________________________________________________________
5776 Real(kind = sp), Dimension (:), Intent (In) :: xvalt
5777 Integer(kind = i4), Dimension (:), Intent (Out) :: IRNGT
5778 ! __________________________________________________________
5779 !
5780 Integer(kind = i4), Dimension (:), Allocatable :: JWRKT
5781 Integer(kind = i4) :: LMTNA, LMTNC
5782 Integer(kind = i4) :: NVAL, IIND, IWRKD, IWRK, IWRKF, JINDA, IINDA, IINDB
5783 !
5784 nval = min(SIZE(xvalt), SIZE(irngt))
5785 If (nval <= 0) Then
5786 Return
5787 End If
5788 !
5789 ! Fill-in the index array, creating ordered couples
5790 !
5791 Do iind = 2, nval, 2
5792 If (xvalt(iind - 1) <= xvalt(iind)) Then
5793 irngt(iind - 1) = iind - 1
5794 irngt(iind) = iind
5795 Else
5796 irngt(iind - 1) = iind
5797 irngt(iind) = iind - 1
5798 End If
5799 End Do
5800 If (modulo(nval, 2) /= 0) Then
5801 irngt(nval) = nval
5802 End If
5803 !
5804 ! We will now have ordered subsets A - B - A - B - ...
5805 ! and merge A and B couples into C - C - ...
5806 !
5807 Allocate (jwrkt(1 : nval))
5808 lmtnc = 2
5809 lmtna = 2
5810 !
5811 ! Iteration. Each time, the length of the ordered subsets
5812 ! is doubled.
5813 !
5814 Do
5815 If (lmtna >= nval) Exit
5816 iwrkf = 0
5817 lmtnc = 2 * lmtnc
5818 iwrk = 0
5819 !
5820 ! Loop on merges of A and B into C
5821 !
5822 Do
5823 iinda = iwrkf
5824 iwrkd = iwrkf + 1
5825 iwrkf = iinda + lmtnc
5826 jinda = iinda + lmtna
5827 If (iwrkf >= nval) Then
5828 If (jinda >= nval) Exit
5829 iwrkf = nval
5830 End If
5831 iindb = jinda
5832 !
5833 ! Shortcut for the case when the max of A is smaller
5834 ! than the min of B (no need to do anything)
5835 !
5836 If (xvalt(irngt(jinda)) <= xvalt(irngt(jinda + 1))) Then
5837 iwrk = iwrkf
5838 cycle
5839 End If
5840 !
5841 ! One steps in the C subset, that we create in the final rank array
5842 !
5843 Do
5844 If (iwrk >= iwrkf) Then
5845 !
5846 ! Make a copy of the rank array for next iteration
5847 !
5848 irngt(iwrkd : iwrkf) = jwrkt(iwrkd : iwrkf)
5849 Exit
5850 End If
5851 !
5852 iwrk = iwrk + 1
5853 !
5854 ! We still have unprocessed values in both A and B
5855 !
5856 If (iinda < jinda) Then
5857 If (iindb < iwrkf) Then
5858 If (xvalt(irngt(iinda + 1)) > xvalt(irngt(iindb + 1))) &
5859 & Then
5860 iindb = iindb + 1
5861 jwrkt(iwrk) = irngt(iindb)
5862 Else
5863 iinda = iinda + 1
5864 jwrkt(iwrk) = irngt(iinda)
5865 End If
5866 Else
5867 !
5868 ! Only A still with unprocessed values
5869 !
5870 iinda = iinda + 1
5871 jwrkt(iwrk) = irngt(iinda)
5872 End If
5873 Else
5874 !
5875 ! Only B still with unprocessed values
5876 !
5877 irngt(iwrkd : iindb) = jwrkt(iwrkd : iindb)
5878 iwrk = iwrkf
5879 Exit
5880 End If
5881 !
5882 End Do
5883 End Do
5884 !
5885 ! The Cs become As and Bs
5886 !
5887 lmtna = 2 * lmtna
5888 End Do
5889 !
5890 ! Clean up
5891 !
5892 Deallocate (jwrkt)
5893 Return
5894 !
5895 End Subroutine r_mrgref
5896
5897 Subroutine i_mrgref (XVALT, IRNGT)
5898 ! Ranks array XVALT into index array IRNGT, using merge-sort
5899 ! __________________________________________________________
5900 ! This version is not optimized for performance, and is thus
5901 ! not as difficult to read as some other ones.
5902 ! Michel Olagnon - April 2000
5903 ! __________________________________________________________
5904 ! __________________________________________________________
5905 Integer(kind = i4), Dimension (:), Intent (In) :: XVALT
5906 Integer(kind = i4), Dimension (:), Intent (Out) :: IRNGT
5907 ! __________________________________________________________
5908 !
5909 Integer(kind = i4), Dimension (:), Allocatable :: JWRKT
5910 Integer(kind = i4) :: LMTNA, LMTNC
5911 Integer(kind = i4) :: NVAL, IIND, IWRKD, IWRK, IWRKF, JINDA, IINDA, IINDB
5912 !
5913 nval = min(SIZE(xvalt), SIZE(irngt))
5914 If (nval <= 0) Then
5915 Return
5916 End If
5917 !
5918 ! Fill-in the index array, creating ordered couples
5919 !
5920 Do iind = 2, nval, 2
5921 If (xvalt(iind - 1) <= xvalt(iind)) Then
5922 irngt(iind - 1) = iind - 1
5923 irngt(iind) = iind
5924 Else
5925 irngt(iind - 1) = iind
5926 irngt(iind) = iind - 1
5927 End If
5928 End Do
5929 If (modulo(nval, 2) /= 0) Then
5930 irngt(nval) = nval
5931 End If
5932 !
5933 ! We will now have ordered subsets A - B - A - B - ...
5934 ! and merge A and B couples into C - C - ...
5935 !
5936 Allocate (jwrkt(1 : nval))
5937 lmtnc = 2
5938 lmtna = 2
5939 !
5940 ! Iteration. Each time, the length of the ordered subsets
5941 ! is doubled.
5942 !
5943 Do
5944 If (lmtna >= nval) Exit
5945 iwrkf = 0
5946 lmtnc = 2 * lmtnc
5947 iwrk = 0
5948 !
5949 ! Loop on merges of A and B into C
5950 !
5951 Do
5952 iinda = iwrkf
5953 iwrkd = iwrkf + 1
5954 iwrkf = iinda + lmtnc
5955 jinda = iinda + lmtna
5956 If (iwrkf >= nval) Then
5957 If (jinda >= nval) Exit
5958 iwrkf = nval
5959 End If
5960 iindb = jinda
5961 !
5962 ! Shortcut for the case when the max of A is smaller
5963 ! than the min of B (no need to do anything)
5964 !
5965 If (xvalt(irngt(jinda)) <= xvalt(irngt(jinda + 1))) Then
5966 iwrk = iwrkf
5967 cycle
5968 End If
5969 !
5970 ! One steps in the C subset, that we create in the final rank array
5971 !
5972 Do
5973 If (iwrk >= iwrkf) Then
5974 !
5975 ! Make a copy of the rank array for next iteration
5976 !
5977 irngt(iwrkd : iwrkf) = jwrkt(iwrkd : iwrkf)
5978 Exit
5979 End If
5980 !
5981 iwrk = iwrk + 1
5982 !
5983 ! We still have unprocessed values in both A and B
5984 !
5985 If (iinda < jinda) Then
5986 If (iindb < iwrkf) Then
5987 If (xvalt(irngt(iinda + 1)) > xvalt(irngt(iindb + 1))) &
5988 & Then
5989 iindb = iindb + 1
5990 jwrkt(iwrk) = irngt(iindb)
5991 Else
5992 iinda = iinda + 1
5993 jwrkt(iwrk) = irngt(iinda)
5994 End If
5995 Else
5996 !
5997 ! Only A still with unprocessed values
5998 !
5999 iinda = iinda + 1
6000 jwrkt(iwrk) = irngt(iinda)
6001 End If
6002 Else
6003 !
6004 ! Only B still with unprocessed values
6005 !
6006 irngt(iwrkd : iindb) = jwrkt(iwrkd : iindb)
6007 iwrk = iwrkf
6008 Exit
6009 End If
6010 !
6011 End Do
6012 End Do
6013 !
6014 ! The Cs become As and Bs
6015 !
6016 lmtna = 2 * lmtna
6017 End Do
6018 !
6019 ! Clean up
6020 !
6021 Deallocate (jwrkt)
6022 Return
6023 !
6024 End Subroutine i_mrgref
6025
6026 Subroutine d_mrgrnk (XDONT, IRNGT)
6027 ! __________________________________________________________
6028 ! MRGRNK = Merge-sort ranking of an array
6029 ! For performance reasons, the first 2 passes are taken
6030 ! out of the standard loop, and use dedicated coding.
6031 ! __________________________________________________________
6032 ! __________________________________________________________
6033 real(kind = dp), Dimension (:), Intent (In) :: xdont
6034 Integer(kind = i4), Dimension (:), Intent (Out) :: IRNGT
6035 ! __________________________________________________________
6036 real(kind = dp) :: xvala, xvalb
6037 !
6038 Integer(kind = i4), Dimension (SIZE(IRNGT)) :: JWRKT
6039 Integer(kind = i4) :: LMTNA, LMTNC, IRNG1, IRNG2
6040 Integer(kind = i4) :: NVAL, IIND, IWRKD, IWRK, IWRKF, JINDA, IINDA, IINDB
6041 !
6042 nval = min(SIZE(xdont), SIZE(irngt))
6043 Select Case (nval)
6044 Case (: 0)
6045 Return
6046 Case (1)
6047 irngt(1) = 1
6048 Return
6049 Case Default
6050
6051 End Select
6052 !
6053 ! Fill-in the index array, creating ordered couples
6054 !
6055 Do iind = 2, nval, 2
6056 If (xdont(iind - 1) <= xdont(iind)) Then
6057 irngt(iind - 1) = iind - 1
6058 irngt(iind) = iind
6059 Else
6060 irngt(iind - 1) = iind
6061 irngt(iind) = iind - 1
6062 End If
6063 End Do
6064 If (modulo(nval, 2) /= 0) Then
6065 irngt(nval) = nval
6066 End If
6067 !
6068 ! We will now have ordered subsets A - B - A - B - ...
6069 ! and merge A and B couples into C - C - ...
6070 !
6071 lmtna = 2
6072 lmtnc = 4
6073 !
6074 ! First iteration. The length of the ordered subsets goes from 2 to 4
6075 !
6076 Do
6077 If (nval <= 2) Exit
6078 !
6079 ! Loop on merges of A and B into C
6080 !
6081 Do iwrkd = 0, nval - 1, 4
6082 If ((iwrkd + 4) > nval) Then
6083 If ((iwrkd + 2) >= nval) Exit
6084 !
6085 ! 1 2 3
6086 !
6087 If (xdont(irngt(iwrkd + 2)) <= xdont(irngt(iwrkd + 3))) Exit
6088 !
6089 ! 1 3 2
6090 !
6091 If (xdont(irngt(iwrkd + 1)) <= xdont(irngt(iwrkd + 3))) Then
6092 irng2 = irngt(iwrkd + 2)
6093 irngt(iwrkd + 2) = irngt(iwrkd + 3)
6094 irngt(iwrkd + 3) = irng2
6095 !
6096 ! 3 1 2
6097 !
6098 Else
6099 irng1 = irngt(iwrkd + 1)
6100 irngt(iwrkd + 1) = irngt(iwrkd + 3)
6101 irngt(iwrkd + 3) = irngt(iwrkd + 2)
6102 irngt(iwrkd + 2) = irng1
6103 End If
6104 If (.true.) Exit ! Exit ! JM
6105 End If
6106 !
6107 ! 1 2 3 4
6108 !
6109 If (xdont(irngt(iwrkd + 2)) <= xdont(irngt(iwrkd + 3))) cycle
6110 !
6111 ! 1 3 x x
6112 !
6113 If (xdont(irngt(iwrkd + 1)) <= xdont(irngt(iwrkd + 3))) Then
6114 irng2 = irngt(iwrkd + 2)
6115 irngt(iwrkd + 2) = irngt(iwrkd + 3)
6116 If (xdont(irng2) <= xdont(irngt(iwrkd + 4))) Then
6117 ! 1 3 2 4
6118 irngt(iwrkd + 3) = irng2
6119 Else
6120 ! 1 3 4 2
6121 irngt(iwrkd + 3) = irngt(iwrkd + 4)
6122 irngt(iwrkd + 4) = irng2
6123 End If
6124 !
6125 ! 3 x x x
6126 !
6127 Else
6128 irng1 = irngt(iwrkd + 1)
6129 irng2 = irngt(iwrkd + 2)
6130 irngt(iwrkd + 1) = irngt(iwrkd + 3)
6131 If (xdont(irng1) <= xdont(irngt(iwrkd + 4))) Then
6132 irngt(iwrkd + 2) = irng1
6133 If (xdont(irng2) <= xdont(irngt(iwrkd + 4))) Then
6134 ! 3 1 2 4
6135 irngt(iwrkd + 3) = irng2
6136 Else
6137 ! 3 1 4 2
6138 irngt(iwrkd + 3) = irngt(iwrkd + 4)
6139 irngt(iwrkd + 4) = irng2
6140 End If
6141 Else
6142 ! 3 4 1 2
6143 irngt(iwrkd + 2) = irngt(iwrkd + 4)
6144 irngt(iwrkd + 3) = irng1
6145 irngt(iwrkd + 4) = irng2
6146 End If
6147 End If
6148 End Do
6149 !
6150 ! The Cs become As and Bs
6151 !
6152 lmtna = 4
6153 If (.true.) Exit ! Exit ! JM
6154 End Do
6155 !
6156 ! Iteration loop. Each time, the length of the ordered subsets
6157 ! is doubled.
6158 !
6159 Do
6160 If (lmtna >= nval) Exit
6161 iwrkf = 0
6162 lmtnc = 2 * lmtnc
6163 !
6164 ! Loop on merges of A and B into C
6165 !
6166 Do
6167 iwrk = iwrkf
6168 iwrkd = iwrkf + 1
6169 jinda = iwrkf + lmtna
6170 iwrkf = iwrkf + lmtnc
6171 If (iwrkf >= nval) Then
6172 If (jinda >= nval) Exit
6173 iwrkf = nval
6174 End If
6175 iinda = 1
6176 iindb = jinda + 1
6177 !
6178 ! Shortcut for the case when the max of A is smaller
6179 ! than the min of B. This line may be activated when the
6180 ! initial set is already close to sorted.
6181 !
6182 ! IF (XDONT(IRNGT(JINDA)) <= XDONT(IRNGT(IINDB))) CYCLE
6183 !
6184 ! One steps in the C subset, that we build in the final rank array
6185 !
6186 ! Make a copy of the rank array for the merge iteration
6187 !
6188 jwrkt(1 : lmtna) = irngt(iwrkd : jinda)
6189 !
6190 xvala = xdont(jwrkt(iinda))
6191 xvalb = xdont(irngt(iindb))
6192 !
6193 Do
6194 iwrk = iwrk + 1
6195 !
6196 ! We still have unprocessed values in both A and B
6197 !
6198 If (xvala > xvalb) Then
6199 irngt(iwrk) = irngt(iindb)
6200 iindb = iindb + 1
6201 If (iindb > iwrkf) Then
6202 ! Only A still with unprocessed values
6203 irngt(iwrk + 1 : iwrkf) = jwrkt(iinda : lmtna)
6204 Exit
6205 End If
6206 xvalb = xdont(irngt(iindb))
6207 Else
6208 irngt(iwrk) = jwrkt(iinda)
6209 iinda = iinda + 1
6210 If (iinda > lmtna) exit! Only B still with unprocessed values
6211 xvala = xdont(jwrkt(iinda))
6212 End If
6213 !
6214 End Do
6215 End Do
6216 !
6217 ! The Cs become As and Bs
6218 !
6219 lmtna = 2 * lmtna
6220 End Do
6221 !
6222 Return
6223 !
6224 End Subroutine d_mrgrnk
6225
6226 Subroutine r_mrgrnk (XDONT, IRNGT)
6227 ! __________________________________________________________
6228 ! MRGRNK = Merge-sort ranking of an array
6229 ! For performance reasons, the first 2 passes are taken
6230 ! out of the standard loop, and use dedicated coding.
6231 ! __________________________________________________________
6232 ! _________________________________________________________
6233 Real(kind = sp), Dimension (:), Intent (In) :: xdont
6234 Integer(kind = i4), Dimension (:), Intent (Out) :: IRNGT
6235 ! __________________________________________________________
6236 Real(kind = sp) :: xvala, xvalb
6237 !
6238 Integer(kind = i4), Dimension (SIZE(IRNGT)) :: JWRKT
6239 Integer(kind = i4) :: LMTNA, LMTNC, IRNG1, IRNG2
6240 Integer(kind = i4) :: NVAL, IIND, IWRKD, IWRK, IWRKF, JINDA, IINDA, IINDB
6241 !
6242 nval = min(SIZE(xdont), SIZE(irngt))
6243 Select Case (nval)
6244 Case (: 0)
6245 Return
6246 Case (1)
6247 irngt(1) = 1
6248 Return
6249 Case Default
6250
6251 End Select
6252 !
6253 ! Fill-in the index array, creating ordered couples
6254 !
6255 Do iind = 2, nval, 2
6256 If (xdont(iind - 1) <= xdont(iind)) Then
6257 irngt(iind - 1) = iind - 1
6258 irngt(iind) = iind
6259 Else
6260 irngt(iind - 1) = iind
6261 irngt(iind) = iind - 1
6262 End If
6263 End Do
6264 If (modulo(nval, 2) /= 0) Then
6265 irngt(nval) = nval
6266 End If
6267 !
6268 ! We will now have ordered subsets A - B - A - B - ...
6269 ! and merge A and B couples into C - C - ...
6270 !
6271 lmtna = 2
6272 lmtnc = 4
6273 !
6274 ! First iteration. The length of the ordered subsets goes from 2 to 4
6275 !
6276 Do
6277 If (nval <= 2) Exit
6278 !
6279 ! Loop on merges of A and B into C
6280 !
6281 Do iwrkd = 0, nval - 1, 4
6282 If ((iwrkd + 4) > nval) Then
6283 If ((iwrkd + 2) >= nval) Exit
6284 !
6285 ! 1 2 3
6286 !
6287 If (xdont(irngt(iwrkd + 2)) <= xdont(irngt(iwrkd + 3))) Exit
6288 !
6289 ! 1 3 2
6290 !
6291 If (xdont(irngt(iwrkd + 1)) <= xdont(irngt(iwrkd + 3))) Then
6292 irng2 = irngt(iwrkd + 2)
6293 irngt(iwrkd + 2) = irngt(iwrkd + 3)
6294 irngt(iwrkd + 3) = irng2
6295 !
6296 ! 3 1 2
6297 !
6298 Else
6299 irng1 = irngt(iwrkd + 1)
6300 irngt(iwrkd + 1) = irngt(iwrkd + 3)
6301 irngt(iwrkd + 3) = irngt(iwrkd + 2)
6302 irngt(iwrkd + 2) = irng1
6303 End If
6304 If (.true.) Exit ! Exit ! JM
6305 End If
6306 !
6307 ! 1 2 3 4
6308 !
6309 If (xdont(irngt(iwrkd + 2)) <= xdont(irngt(iwrkd + 3))) cycle
6310 !
6311 ! 1 3 x x
6312 !
6313 If (xdont(irngt(iwrkd + 1)) <= xdont(irngt(iwrkd + 3))) Then
6314 irng2 = irngt(iwrkd + 2)
6315 irngt(iwrkd + 2) = irngt(iwrkd + 3)
6316 If (xdont(irng2) <= xdont(irngt(iwrkd + 4))) Then
6317 ! 1 3 2 4
6318 irngt(iwrkd + 3) = irng2
6319 Else
6320 ! 1 3 4 2
6321 irngt(iwrkd + 3) = irngt(iwrkd + 4)
6322 irngt(iwrkd + 4) = irng2
6323 End If
6324 !
6325 ! 3 x x x
6326 !
6327 Else
6328 irng1 = irngt(iwrkd + 1)
6329 irng2 = irngt(iwrkd + 2)
6330 irngt(iwrkd + 1) = irngt(iwrkd + 3)
6331 If (xdont(irng1) <= xdont(irngt(iwrkd + 4))) Then
6332 irngt(iwrkd + 2) = irng1
6333 If (xdont(irng2) <= xdont(irngt(iwrkd + 4))) Then
6334 ! 3 1 2 4
6335 irngt(iwrkd + 3) = irng2
6336 Else
6337 ! 3 1 4 2
6338 irngt(iwrkd + 3) = irngt(iwrkd + 4)
6339 irngt(iwrkd + 4) = irng2
6340 End If
6341 Else
6342 ! 3 4 1 2
6343 irngt(iwrkd + 2) = irngt(iwrkd + 4)
6344 irngt(iwrkd + 3) = irng1
6345 irngt(iwrkd + 4) = irng2
6346 End If
6347 End If
6348 End Do
6349 !
6350 ! The Cs become As and Bs
6351 !
6352 lmtna = 4
6353 If (.true.) Exit ! Exit ! JM
6354 End Do
6355 !
6356 ! Iteration loop. Each time, the length of the ordered subsets
6357 ! is doubled.
6358 !
6359 Do
6360 If (lmtna >= nval) Exit
6361 iwrkf = 0
6362 lmtnc = 2 * lmtnc
6363 !
6364 ! Loop on merges of A and B into C
6365 !
6366 Do
6367 iwrk = iwrkf
6368 iwrkd = iwrkf + 1
6369 jinda = iwrkf + lmtna
6370 iwrkf = iwrkf + lmtnc
6371 If (iwrkf >= nval) Then
6372 If (jinda >= nval) Exit
6373 iwrkf = nval
6374 End If
6375 iinda = 1
6376 iindb = jinda + 1
6377 !
6378 ! Shortcut for the case when the max of A is smaller
6379 ! than the min of B. This line may be activated when the
6380 ! initial set is already close to sorted.
6381 !
6382 ! IF (XDONT(IRNGT(JINDA)) <= XDONT(IRNGT(IINDB))) CYCLE
6383 !
6384 ! One steps in the C subset, that we build in the final rank array
6385 !
6386 ! Make a copy of the rank array for the merge iteration
6387 !
6388 jwrkt(1 : lmtna) = irngt(iwrkd : jinda)
6389 !
6390 xvala = xdont(jwrkt(iinda))
6391 xvalb = xdont(irngt(iindb))
6392 !
6393 Do
6394 iwrk = iwrk + 1
6395 !
6396 ! We still have unprocessed values in both A and B
6397 !
6398 If (xvala > xvalb) Then
6399 irngt(iwrk) = irngt(iindb)
6400 iindb = iindb + 1
6401 If (iindb > iwrkf) Then
6402 ! Only A still with unprocessed values
6403 irngt(iwrk + 1 : iwrkf) = jwrkt(iinda : lmtna)
6404 Exit
6405 End If
6406 xvalb = xdont(irngt(iindb))
6407 Else
6408 irngt(iwrk) = jwrkt(iinda)
6409 iinda = iinda + 1
6410 If (iinda > lmtna) exit! Only B still with unprocessed values
6411 xvala = xdont(jwrkt(iinda))
6412 End If
6413 !
6414 End Do
6415 End Do
6416 !
6417 ! The Cs become As and Bs
6418 !
6419 lmtna = 2 * lmtna
6420 End Do
6421 !
6422 Return
6423 !
6424 End Subroutine r_mrgrnk
6425
6426 Subroutine i_mrgrnk (XDONT, IRNGT)
6427 ! __________________________________________________________
6428 ! MRGRNK = Merge-sort ranking of an array
6429 ! For performance reasons, the first 2 passes are taken
6430 ! out of the standard loop, and use dedicated coding.
6431 ! __________________________________________________________
6432 ! __________________________________________________________
6433 Integer(kind = i4), Dimension (:), Intent (In) :: XDONT
6434 Integer(kind = i4), Dimension (:), Intent (Out) :: IRNGT
6435 ! __________________________________________________________
6436 Integer(kind = i4) :: XVALA, XVALB
6437 !
6438 Integer(kind = i4), Dimension (SIZE(IRNGT)) :: JWRKT
6439 Integer(kind = i4) :: LMTNA, LMTNC, IRNG1, IRNG2
6440 Integer(kind = i4) :: NVAL, IIND, IWRKD, IWRK, IWRKF, JINDA, IINDA, IINDB
6441 !
6442 nval = min(SIZE(xdont), SIZE(irngt))
6443 Select Case (nval)
6444 Case (: 0)
6445 Return
6446 Case (1)
6447 irngt(1) = 1
6448 Return
6449 Case Default
6450
6451 End Select
6452 !
6453 ! Fill-in the index array, creating ordered couples
6454 !
6455 Do iind = 2, nval, 2
6456 If (xdont(iind - 1) <= xdont(iind)) Then
6457 irngt(iind - 1) = iind - 1
6458 irngt(iind) = iind
6459 Else
6460 irngt(iind - 1) = iind
6461 irngt(iind) = iind - 1
6462 End If
6463 End Do
6464 If (modulo(nval, 2) /= 0) Then
6465 irngt(nval) = nval
6466 End If
6467 !
6468 ! We will now have ordered subsets A - B - A - B - ...
6469 ! and merge A and B couples into C - C - ...
6470 !
6471 lmtna = 2
6472 lmtnc = 4
6473 !
6474 ! First iteration. The length of the ordered subsets goes from 2 to 4
6475 !
6476 Do
6477 If (nval <= 2) Exit
6478 !
6479 ! Loop on merges of A and B into C
6480 !
6481 Do iwrkd = 0, nval - 1, 4
6482 If ((iwrkd + 4) > nval) Then
6483 If ((iwrkd + 2) >= nval) Exit
6484 !
6485 ! 1 2 3
6486 !
6487 If (xdont(irngt(iwrkd + 2)) <= xdont(irngt(iwrkd + 3))) Exit
6488 !
6489 ! 1 3 2
6490 !
6491 If (xdont(irngt(iwrkd + 1)) <= xdont(irngt(iwrkd + 3))) Then
6492 irng2 = irngt(iwrkd + 2)
6493 irngt(iwrkd + 2) = irngt(iwrkd + 3)
6494 irngt(iwrkd + 3) = irng2
6495 !
6496 ! 3 1 2
6497 !
6498 Else
6499 irng1 = irngt(iwrkd + 1)
6500 irngt(iwrkd + 1) = irngt(iwrkd + 3)
6501 irngt(iwrkd + 3) = irngt(iwrkd + 2)
6502 irngt(iwrkd + 2) = irng1
6503 End If
6504 If (.true.) Exit ! Exit ! JM
6505 End If
6506 !
6507 ! 1 2 3 4
6508 !
6509 If (xdont(irngt(iwrkd + 2)) <= xdont(irngt(iwrkd + 3))) cycle
6510 !
6511 ! 1 3 x x
6512 !
6513 If (xdont(irngt(iwrkd + 1)) <= xdont(irngt(iwrkd + 3))) Then
6514 irng2 = irngt(iwrkd + 2)
6515 irngt(iwrkd + 2) = irngt(iwrkd + 3)
6516 If (xdont(irng2) <= xdont(irngt(iwrkd + 4))) Then
6517 ! 1 3 2 4
6518 irngt(iwrkd + 3) = irng2
6519 Else
6520 ! 1 3 4 2
6521 irngt(iwrkd + 3) = irngt(iwrkd + 4)
6522 irngt(iwrkd + 4) = irng2
6523 End If
6524 !
6525 ! 3 x x x
6526 !
6527 Else
6528 irng1 = irngt(iwrkd + 1)
6529 irng2 = irngt(iwrkd + 2)
6530 irngt(iwrkd + 1) = irngt(iwrkd + 3)
6531 If (xdont(irng1) <= xdont(irngt(iwrkd + 4))) Then
6532 irngt(iwrkd + 2) = irng1
6533 If (xdont(irng2) <= xdont(irngt(iwrkd + 4))) Then
6534 ! 3 1 2 4
6535 irngt(iwrkd + 3) = irng2
6536 Else
6537 ! 3 1 4 2
6538 irngt(iwrkd + 3) = irngt(iwrkd + 4)
6539 irngt(iwrkd + 4) = irng2
6540 End If
6541 Else
6542 ! 3 4 1 2
6543 irngt(iwrkd + 2) = irngt(iwrkd + 4)
6544 irngt(iwrkd + 3) = irng1
6545 irngt(iwrkd + 4) = irng2
6546 End If
6547 End If
6548 End Do
6549 !
6550 ! The Cs become As and Bs
6551 !
6552 lmtna = 4
6553 If (.true.) Exit ! Exit ! JM
6554 End Do
6555 !
6556 ! Iteration loop. Each time, the length of the ordered subsets
6557 ! is doubled.
6558 !
6559 Do
6560 If (lmtna >= nval) Exit
6561 iwrkf = 0
6562 lmtnc = 2 * lmtnc
6563 !
6564 ! Loop on merges of A and B into C
6565 !
6566 Do
6567 iwrk = iwrkf
6568 iwrkd = iwrkf + 1
6569 jinda = iwrkf + lmtna
6570 iwrkf = iwrkf + lmtnc
6571 If (iwrkf >= nval) Then
6572 If (jinda >= nval) Exit
6573 iwrkf = nval
6574 End If
6575 iinda = 1
6576 iindb = jinda + 1
6577 !
6578 ! Shortcut for the case when the max of A is smaller
6579 ! than the min of B. This line may be activated when the
6580 ! initial set is already close to sorted.
6581 !
6582 ! IF (XDONT(IRNGT(JINDA)) <= XDONT(IRNGT(IINDB))) CYCLE
6583 !
6584 ! One steps in the C subset, that we build in the final rank array
6585 !
6586 ! Make a copy of the rank array for the merge iteration
6587 !
6588 jwrkt(1 : lmtna) = irngt(iwrkd : jinda)
6589 !
6590 xvala = xdont(jwrkt(iinda))
6591 xvalb = xdont(irngt(iindb))
6592 !
6593 Do
6594 iwrk = iwrk + 1
6595 !
6596 ! We still have unprocessed values in both A and B
6597 !
6598 If (xvala > xvalb) Then
6599 irngt(iwrk) = irngt(iindb)
6600 iindb = iindb + 1
6601 If (iindb > iwrkf) Then
6602 ! Only A still with unprocessed values
6603 irngt(iwrk + 1 : iwrkf) = jwrkt(iinda : lmtna)
6604 Exit
6605 End If
6606 xvalb = xdont(irngt(iindb))
6607 Else
6608 irngt(iwrk) = jwrkt(iinda)
6609 iinda = iinda + 1
6610 If (iinda > lmtna) exit! Only B still with unprocessed values
6611 xvala = xdont(jwrkt(iinda))
6612 End If
6613 !
6614 End Do
6615 End Do
6616 !
6617 ! The Cs become As and Bs
6618 !
6619 lmtna = 2 * lmtna
6620 End Do
6621 !
6622 Return
6623 !
6624 End Subroutine i_mrgrnk
6625
6626 Subroutine c_mrgrnk (XDONT, IRNGT)
6627 ! __________________________________________________________
6628 ! MRGRNK = Merge-sort ranking of an array
6629 ! For performance reasons, the first 2 passes are taken
6630 ! out of the standard loop, and use dedicated coding.
6631 ! __________________________________________________________
6632 ! __________________________________________________________
6633 character(*), Dimension (:), Intent (In) :: XDONT
6634 Integer(kind = i4), Dimension (:), Intent (Out) :: IRNGT
6635 ! __________________________________________________________
6636 character(len(XDONT)) :: XVALA, XVALB
6637 !
6638 Integer(kind = i4), Dimension (SIZE(IRNGT)) :: JWRKT
6639 Integer(kind = i4) :: LMTNA, LMTNC, IRNG1, IRNG2
6640 Integer(kind = i4) :: NVAL, IIND, IWRKD, IWRK, IWRKF, JINDA, IINDA, IINDB
6641 !
6642 nval = min(SIZE(xdont), SIZE(irngt))
6643 Select Case (nval)
6644 Case (: 0)
6645 Return
6646 Case (1)
6647 irngt(1) = 1
6648 Return
6649 Case Default
6650
6651 End Select
6652 !
6653 ! Fill-in the index array, creating ordered couples
6654 !
6655 Do iind = 2, nval, 2
6656 If (xdont(iind - 1) <= xdont(iind)) Then
6657 irngt(iind - 1) = iind - 1
6658 irngt(iind) = iind
6659 Else
6660 irngt(iind - 1) = iind
6661 irngt(iind) = iind - 1
6662 End If
6663 End Do
6664 If (modulo(nval, 2) /= 0) Then
6665 irngt(nval) = nval
6666 End If
6667 !
6668 ! We will now have ordered subsets A - B - A - B - ...
6669 ! and merge A and B couples into C - C - ...
6670 !
6671 lmtna = 2
6672 lmtnc = 4
6673 !
6674 ! First iteration. The length of the ordered subsets goes from 2 to 4
6675 !
6676 Do
6677 If (nval <= 2) Exit
6678 !
6679 ! Loop on merges of A and B into C
6680 !
6681 Do iwrkd = 0, nval - 1, 4
6682 If ((iwrkd + 4) > nval) Then
6683 If ((iwrkd + 2) >= nval) Exit
6684 !
6685 ! 1 2 3
6686 !
6687 If (xdont(irngt(iwrkd + 2)) <= xdont(irngt(iwrkd + 3))) Exit
6688 !
6689 ! 1 3 2
6690 !
6691 If (xdont(irngt(iwrkd + 1)) <= xdont(irngt(iwrkd + 3))) Then
6692 irng2 = irngt(iwrkd + 2)
6693 irngt(iwrkd + 2) = irngt(iwrkd + 3)
6694 irngt(iwrkd + 3) = irng2
6695 !
6696 ! 3 1 2
6697 !
6698 Else
6699 irng1 = irngt(iwrkd + 1)
6700 irngt(iwrkd + 1) = irngt(iwrkd + 3)
6701 irngt(iwrkd + 3) = irngt(iwrkd + 2)
6702 irngt(iwrkd + 2) = irng1
6703 End If
6704 If (.true.) Exit ! Exit ! JM
6705 End If
6706 !
6707 ! 1 2 3 4
6708 !
6709 If (xdont(irngt(iwrkd + 2)) <= xdont(irngt(iwrkd + 3))) cycle
6710 !
6711 ! 1 3 x x
6712 !
6713 If (xdont(irngt(iwrkd + 1)) <= xdont(irngt(iwrkd + 3))) Then
6714 irng2 = irngt(iwrkd + 2)
6715 irngt(iwrkd + 2) = irngt(iwrkd + 3)
6716 If (xdont(irng2) <= xdont(irngt(iwrkd + 4))) Then
6717 ! 1 3 2 4
6718 irngt(iwrkd + 3) = irng2
6719 Else
6720 ! 1 3 4 2
6721 irngt(iwrkd + 3) = irngt(iwrkd + 4)
6722 irngt(iwrkd + 4) = irng2
6723 End If
6724 !
6725 ! 3 x x x
6726 !
6727 Else
6728 irng1 = irngt(iwrkd + 1)
6729 irng2 = irngt(iwrkd + 2)
6730 irngt(iwrkd + 1) = irngt(iwrkd + 3)
6731 If (xdont(irng1) <= xdont(irngt(iwrkd + 4))) Then
6732 irngt(iwrkd + 2) = irng1
6733 If (xdont(irng2) <= xdont(irngt(iwrkd + 4))) Then
6734 ! 3 1 2 4
6735 irngt(iwrkd + 3) = irng2
6736 Else
6737 ! 3 1 4 2
6738 irngt(iwrkd + 3) = irngt(iwrkd + 4)
6739 irngt(iwrkd + 4) = irng2
6740 End If
6741 Else
6742 ! 3 4 1 2
6743 irngt(iwrkd + 2) = irngt(iwrkd + 4)
6744 irngt(iwrkd + 3) = irng1
6745 irngt(iwrkd + 4) = irng2
6746 End If
6747 End If
6748 End Do
6749 !
6750 ! The Cs become As and Bs
6751 !
6752 lmtna = 4
6753 If (.true.) Exit ! Exit ! JM
6754 End Do
6755 !
6756 ! Iteration loop. Each time, the length of the ordered subsets
6757 ! is doubled.
6758 !
6759 Do
6760 If (lmtna >= nval) Exit
6761 iwrkf = 0
6762 lmtnc = 2 * lmtnc
6763 !
6764 ! Loop on merges of A and B into C
6765 !
6766 Do
6767 iwrk = iwrkf
6768 iwrkd = iwrkf + 1
6769 jinda = iwrkf + lmtna
6770 iwrkf = iwrkf + lmtnc
6771 If (iwrkf >= nval) Then
6772 If (jinda >= nval) Exit
6773 iwrkf = nval
6774 End If
6775 iinda = 1
6776 iindb = jinda + 1
6777 !
6778 ! Shortcut for the case when the max of A is smaller
6779 ! than the min of B. This line may be activated when the
6780 ! initial set is already close to sorted.
6781 !
6782 ! IF (XDONT(IRNGT(JINDA)) <= XDONT(IRNGT(IINDB))) CYCLE
6783 !
6784 ! One steps in the C subset, that we build in the final rank array
6785 !
6786 ! Make a copy of the rank array for the merge iteration
6787 !
6788 jwrkt(1 : lmtna) = irngt(iwrkd : jinda)
6789 !
6790 xvala = xdont(jwrkt(iinda))
6791 xvalb = xdont(irngt(iindb))
6792 !
6793 Do
6794 iwrk = iwrk + 1
6795 !
6796 ! We still have unprocessed values in both A and B
6797 !
6798 If (xvala > xvalb) Then
6799 irngt(iwrk) = irngt(iindb)
6800 iindb = iindb + 1
6801 If (iindb > iwrkf) Then
6802 ! Only A still with unprocessed values
6803 irngt(iwrk + 1 : iwrkf) = jwrkt(iinda : lmtna)
6804 Exit
6805 End If
6806 xvalb = xdont(irngt(iindb))
6807 Else
6808 irngt(iwrk) = jwrkt(iinda)
6809 iinda = iinda + 1
6810 If (iinda > lmtna) exit! Only B still with unprocessed values
6811 xvala = xdont(jwrkt(iinda))
6812 End If
6813 !
6814 End Do
6815 End Do
6816 !
6817 ! The Cs become As and Bs
6818 !
6819 lmtna = 2 * lmtna
6820 End Do
6821 !
6822 Return
6823 !
6824 End Subroutine c_mrgrnk
6825
6826 Subroutine d_mulcnt (XDONT, IMULT)
6827 ! MULCNT = Give for each array value its multiplicity
6828 ! (number of times that it appears in the array)
6829 ! __________________________________________________________
6830 ! Michel Olagnon - Mar. 2000
6831 ! __________________________________________________________
6832 ! __________________________________________________________
6833 real(kind = dp), Dimension (:), Intent (In) :: xdont
6834 Integer(kind = i4), Dimension (:), Intent (Out) :: IMULT
6835 ! __________________________________________________________
6836 !
6837 Integer(kind = i4), Dimension (Size(XDONT)) :: IWRKT
6838 Integer(kind = i4), Dimension (Size(XDONT)) :: ICNTT
6839 Integer(kind = i4) :: ICRS
6840 ! __________________________________________________________
6841 Call uniinv (xdont, iwrkt)
6842 icntt = 0
6843 Do icrs = 1, Size(xdont)
6844 icntt(iwrkt(icrs)) = icntt(iwrkt(icrs)) + 1
6845 End Do
6846 Do icrs = 1, Size(xdont)
6847 imult(icrs) = icntt(iwrkt(icrs))
6848 End Do
6849
6850 !
6851 End Subroutine d_mulcnt
6852
6853 Subroutine r_mulcnt (XDONT, IMULT)
6854 ! MULCNT = Give for each array value its multiplicity
6855 ! (number of times that it appears in the array)
6856 ! __________________________________________________________
6857 ! Michel Olagnon - Mar. 2000
6858 ! __________________________________________________________
6859 ! _________________________________________________________
6860 Real(kind = sp), Dimension (:), Intent (In) :: xdont
6861 Integer(kind = i4), Dimension (:), Intent (Out) :: IMULT
6862 ! __________________________________________________________
6863 !
6864 Integer(kind = i4), Dimension (Size(XDONT)) :: IWRKT
6865 Integer(kind = i4), Dimension (Size(XDONT)) :: ICNTT
6866 Integer(kind = i4) :: ICRS
6867 ! __________________________________________________________
6868 Call uniinv (xdont, iwrkt)
6869 icntt = 0
6870 Do icrs = 1, Size(xdont)
6871 icntt(iwrkt(icrs)) = icntt(iwrkt(icrs)) + 1
6872 End Do
6873 Do icrs = 1, Size(xdont)
6874 imult(icrs) = icntt(iwrkt(icrs))
6875 End Do
6876
6877 !
6878 End Subroutine r_mulcnt
6879
6880 Subroutine i_mulcnt (XDONT, IMULT)
6881 ! MULCNT = Give for each array value its multiplicity
6882 ! (number of times that it appears in the array)
6883 ! __________________________________________________________
6884 ! Michel Olagnon - Mar. 2000
6885 ! __________________________________________________________
6886 ! __________________________________________________________
6887 Integer(kind = i4), Dimension (:), Intent (In) :: XDONT
6888 Integer(kind = i4), Dimension (:), Intent (Out) :: IMULT
6889 ! __________________________________________________________
6890 !
6891 Integer(kind = i4), Dimension (Size(XDONT)) :: IWRKT
6892 Integer(kind = i4), Dimension (Size(XDONT)) :: ICNTT
6893 Integer(kind = i4) :: ICRS
6894 ! __________________________________________________________
6895 Call uniinv (xdont, iwrkt)
6896 icntt = 0
6897 Do icrs = 1, Size(xdont)
6898 icntt(iwrkt(icrs)) = icntt(iwrkt(icrs)) + 1
6899 End Do
6900 Do icrs = 1, Size(xdont)
6901 imult(icrs) = icntt(iwrkt(icrs))
6902 End Do
6903
6904 !
6905 End Subroutine i_mulcnt
6906
6907 Subroutine d_rapknr (XDONT, IRNGT, NORD)
6908 ! Ranks partially XDONT by IRNGT, up to order NORD, in decreasing order.
6909 ! rapknr = (rnkpar backwards)
6910 ! __________________________________________________________
6911 ! This routine uses a pivoting strategy such as the one of
6912 ! finding the median based on the quicksort algorithm, but
6913 ! we skew the pivot choice to try to bring it to NORD as
6914 ! fast as possible. It uses 2 temporary arrays, where it
6915 ! stores the indices of the values larger than the pivot
6916 ! (IHIGT), and the indices of values smaller than the pivot
6917 ! that we might still need later on (ILOWT). It iterates
6918 ! until it can bring the number of values in IHIGT to
6919 ! exactly NORD, and then uses an insertion sort to rank
6920 ! this set, since it is supposedly small.
6921 ! Michel Olagnon - Feb. 2011
6922 ! __________________________________________________________
6923 ! __________________________________________________________
6924 real(kind = dp), Dimension (:), Intent (In) :: xdont
6925 Integer(kind = i4), Dimension (:), Intent (Out) :: IRNGT
6926 Integer(kind = i4), Intent (In) :: NORD
6927 ! __________________________________________________________
6928 real(kind = dp) :: xpiv, xpiv0, xwrk, xwrk1, xmin, xmax
6929 !
6930 Integer(kind = i4), Dimension (SIZE(XDONT)) :: ILOWT, IHIGT
6931 Integer(kind = i4) :: NDON, JHIG, JLOW, IHIG, IWRK, IWRK1, IWRK2, IWRK3
6932 Integer(kind = i4) :: IDEB, JDEB, IMIL, IFIN, NWRK, ICRS, IDCR, ILOW
6933 Integer(kind = i4) :: JLM2, JLM1, JHM2, JHM1
6934 !
6935 ndon = SIZE (xdont)
6936 !
6937 ! First loop is used to fill-in ILOWT, IHIGT at the same time
6938 !
6939 If (ndon < 2) Then
6940 If (nord >= 1) irngt(1) = 1
6941 Return
6942 End If
6943 !
6944 ! One chooses a pivot, best estimate possible to put fractile near
6945 ! mid-point of the set of high values.
6946 !
6947 If (xdont(2) < xdont(1)) Then
6948 ilowt(1) = 2
6949 ihigt(1) = 1
6950 Else
6951 ilowt(1) = 1
6952 ihigt(1) = 2
6953 End If
6954 !
6955 If (ndon < 3) Then
6956 If (nord >= 1) irngt(1) = ihigt(1)
6957 If (nord >= 2) irngt(2) = ilowt(1)
6958 Return
6959 End If
6960 ! ---
6961 If (xdont(3) > xdont(ilowt(1))) Then
6962 ilowt(2) = ilowt(1)
6963 If (xdont(3) > xdont(ihigt(1))) Then
6964 ilowt(1) = ihigt(1)
6965 ihigt(1) = 3
6966 Else
6967 ilowt(1) = 3
6968 End If
6969 Else
6970 ilowt(2) = 3
6971 End If
6972 ! ---
6973 If (ndon < 4) Then
6974 If (nord >= 1) irngt(1) = ihigt(1)
6975 If (nord >= 2) irngt(2) = ilowt(1)
6976 If (nord >= 3) irngt(3) = ilowt(2)
6977 Return
6978 End If
6979 !
6980 If (xdont(ndon) > xdont(ilowt(1))) Then
6981 ilowt(3) = ilowt(2)
6982 ilowt(2) = ilowt(1)
6983 If (xdont(ndon) > xdont(ihigt(1))) Then
6984 ilowt(1) = ihigt(1)
6985 ihigt(1) = ndon
6986 Else
6987 ilowt(1) = ndon
6988 End If
6989 Else
6990 if (xdont(ndon) > xdont(ilowt(2))) Then
6991 ilowt(3) = ilowt(2)
6992 ilowt(2) = ndon
6993 else
6994 ilowt(3) = ndon
6995 end if
6996 End If
6997 !
6998 If (ndon < 5) Then
6999 If (nord >= 1) irngt(1) = ihigt(1)
7000 If (nord >= 2) irngt(2) = ilowt(1)
7001 If (nord >= 3) irngt(3) = ilowt(2)
7002 If (nord >= 4) irngt(4) = ilowt(3)
7003 Return
7004 End If
7005 ! ---
7006 jdeb = 0
7007 ideb = jdeb + 1
7008 jhig = ideb
7009 jlow = 3
7010 xpiv = xdont(ihigt(ideb)) + real(2 * nord, dp) / real(ndon + nord, dp) * &
7011 (xdont(ilowt(3)) - xdont(ihigt(ideb)))
7012 If (xpiv >= xdont(ilowt(1))) Then
7013 xpiv = xdont(ihigt(ideb)) + real(2 * nord, dp) / real(ndon + nord, dp) * &
7014 (xdont(ilowt(2)) - xdont(ihigt(ideb)))
7015 If (xpiv >= xdont(ilowt(1))) &
7016 xpiv = xdont(ihigt(ideb)) + real(2 * nord, dp) / real(ndon + nord, dp) * &
7017 (xdont(ilowt(1)) - xdont(ihigt(ideb)))
7018 End If
7019 xpiv0 = xpiv
7020 ! ---
7021 ! One puts values < pivot in the end and those >= pivot
7022 ! at the beginning. This is split in 2 cases, so that
7023 ! we can skip the loop test a number of times.
7024 ! As we are also filling in the work arrays at the same time
7025 ! we stop filling in the ILOWT array as soon as we have more
7026 ! than enough values in IHIGT.
7027 !
7028 !
7029 If (xdont(ndon) < xpiv) Then
7030 icrs = 3
7031 Do
7032 icrs = icrs + 1
7033 If (xdont(icrs) < xpiv) Then
7034 If (icrs >= ndon) Exit
7035 jlow = jlow + 1
7036 ilowt(jlow) = icrs
7037 Else
7038 jhig = jhig + 1
7039 ihigt(jhig) = icrs
7040 If (jhig >= nord) Exit
7041 End If
7042 End Do
7043 !
7044 ! One restricts further processing because it is no use
7045 ! to store more low values
7046 !
7047 If (icrs < ndon - 1) Then
7048 Do
7049 icrs = icrs + 1
7050 If (xdont(icrs) >= xpiv) Then
7051 jhig = jhig + 1
7052 ihigt(jhig) = icrs
7053 Else If (icrs >= ndon) Then
7054 Exit
7055 End If
7056 End Do
7057 End If
7058 !
7059 ! ---
7060 Else
7061 !
7062 ! Same as above, but this is not as easy to optimize, so the
7063 ! DO-loop is kept
7064 !
7065 Do icrs = 4, ndon - 1
7066 If (xdont(icrs) < xpiv) Then
7067 jlow = jlow + 1
7068 ilowt(jlow) = icrs
7069 Else
7070 jhig = jhig + 1
7071 ihigt(jhig) = icrs
7072 If (jhig >= nord) Exit
7073 End If
7074 End Do
7075 !
7076 If (icrs < ndon - 1) Then
7077 Do
7078 icrs = icrs + 1
7079 If (xdont(icrs) >= xpiv) Then
7080 If (icrs >= ndon) Exit
7081 jhig = jhig + 1
7082 ihigt(jhig) = icrs
7083 End If
7084 End Do
7085 End If
7086 End If
7087 ! ---
7088 jlm2 = 0
7089 jlm1 = 0
7090 jhm2 = 0
7091 jhm1 = 0
7092 Do
7093 if (jhig == nord) Exit
7094 If (jhm2 == jhig .And. jlm2 == jlow) Then
7095 !
7096 ! We are oscillating. Perturbate by bringing JHIG closer by one
7097 ! to NORD
7098 !
7099 If (nord > jhig) Then
7100 xmax = xdont(ilowt(1))
7101 ilow = 1
7102 Do icrs = 2, jlow
7103 If (xdont(ilowt(icrs)) > xmax) Then
7104 xmax = xdont(ilowt(icrs))
7105 ilow = icrs
7106 End If
7107 End Do
7108 !
7109 jhig = jhig + 1
7110 ihigt(jhig) = ilowt(ilow)
7111 ilowt(ilow) = ilowt(jlow)
7112 jlow = jlow - 1
7113 Else
7114 ihig = ihigt(jhig)
7115 xmin = xdont(ihig)
7116 Do icrs = 1, jhig
7117 If (xdont(ihigt(icrs)) < xmin) Then
7118 iwrk = ihigt(icrs)
7119 xmin = xdont(iwrk)
7120 ihigt(icrs) = ihig
7121 ihig = iwrk
7122 End If
7123 End Do
7124 jhig = jhig - 1
7125 End If
7126 End If
7127 jlm2 = jlm1
7128 jlm1 = jlow
7129 jhm2 = jhm1
7130 jhm1 = jhig
7131 ! ---
7132 ! We try to bring the number of values in the high values set
7133 ! closer to NORD.
7134 !
7135 Select Case (nord - jhig)
7136 Case (2 :)
7137 !
7138 ! Not enough values in low part, at least 2 are missing
7139 !
7140 Select Case (jlow)
7141 !!!!! CASE DEFAULT
7142 !!!!! write (*,*) "Assertion failed"
7143 !!!!! STOP
7144 !
7145 ! We make a special case when we have so few values in
7146 ! the low values set that it is bad performance to choose a pivot
7147 ! and apply the general algorithm.
7148 !
7149 Case (2)
7150 If (xdont(ilowt(1)) >= xdont(ilowt(2))) Then
7151 jhig = jhig + 1
7152 ihigt(jhig) = ilowt(1)
7153 jhig = jhig + 1
7154 ihigt(jhig) = ilowt(2)
7155 Else
7156 jhig = jhig + 1
7157 ihigt(jhig) = ilowt(2)
7158 jhig = jhig + 1
7159 ihigt(jhig) = ilowt(1)
7160 End If
7161 Exit
7162 ! ---
7163 Case (3)
7164 !
7165 !
7166 iwrk1 = ilowt(1)
7167 iwrk2 = ilowt(2)
7168 iwrk3 = ilowt(3)
7169 If (xdont(iwrk2) > xdont(iwrk1)) Then
7170 ilowt(1) = iwrk2
7171 ilowt(2) = iwrk1
7172 iwrk2 = iwrk1
7173 End If
7174 If (xdont(iwrk2) < xdont(iwrk3)) Then
7175 ilowt(3) = iwrk2
7176 ilowt(2) = iwrk3
7177 iwrk2 = iwrk3
7178 If (xdont(iwrk2) > xdont(ilowt(1))) Then
7179 ilowt(2) = ilowt(1)
7180 ilowt(1) = iwrk2
7181 End If
7182 End If
7183 jlow = 0
7184 Do icrs = jhig + 1, nord
7185 jlow = jlow + 1
7186 ihigt(icrs) = ilowt(jlow)
7187 End Do
7188 jhig = nord
7189 Exit
7190 ! ---
7191 Case (4 :)
7192 !
7193 !
7194 xpiv0 = xpiv
7195 ifin = jlow
7196 !
7197 ! One chooses a pivot from the 2 first values and the last one.
7198 ! This should ensure sufficient renewal between iterations to
7199 ! avoid worst case behavior effects.
7200 !
7201 iwrk1 = ilowt(1)
7202 iwrk2 = ilowt(2)
7203 iwrk3 = ilowt(ifin)
7204 If (xdont(iwrk2) > xdont(iwrk1)) Then
7205 ilowt(1) = iwrk2
7206 ilowt(2) = iwrk1
7207 iwrk2 = iwrk1
7208 End If
7209 If (xdont(iwrk2) < xdont(iwrk3)) Then
7210 ilowt(ifin) = iwrk2
7211 ilowt(2) = iwrk3
7212 iwrk2 = iwrk3
7213 If (xdont(iwrk2) > xdont(ihigt(1))) Then
7214 ilowt(2) = ilowt(1)
7215 ilowt(1) = iwrk2
7216 End If
7217 End If
7218 !
7219 jdeb = jhig
7220 nwrk = nord - jhig
7221 iwrk1 = ilowt(1)
7222 jhig = jhig + 1
7223 ihigt(jhig) = iwrk1
7224 xpiv = xdont(iwrk1) + real(nwrk, dp) / real(nord + nwrk, dp) * &
7225 (xdont(ilowt(ifin)) - xdont(iwrk1))
7226 !
7227 ! One takes values >= pivot to IHIGT
7228 ! Again, 2 parts, one where we take care of the remaining
7229 ! low values because we might still need them, and the
7230 ! other when we know that we will have more than enough
7231 ! high values in the end.
7232 ! ---
7233 jlow = 0
7234 Do icrs = 2, ifin
7235 If (xdont(ilowt(icrs)) >= xpiv) Then
7236 jhig = jhig + 1
7237 ihigt(jhig) = ilowt(icrs)
7238 If (jhig >= nord) Exit
7239 Else
7240 jlow = jlow + 1
7241 ilowt(jlow) = ilowt(icrs)
7242 End If
7243 End Do
7244 !
7245 Do icrs = icrs + 1, ifin
7246 If (xdont(ilowt(icrs)) >= xpiv) Then
7247 jhig = jhig + 1
7248 ihigt(jhig) = ilowt(icrs)
7249 End If
7250 End Do
7251 End Select
7252 ! ---
7253 !
7254 Case (1)
7255 !
7256 ! Only 1 value is missing in high part
7257 !
7258 xmax = xdont(ilowt(1))
7259 ilow = 1
7260 Do icrs = 2, jlow
7261 If (xdont(ilowt(icrs)) > xmax) Then
7262 xmax = xdont(ilowt(icrs))
7263 ilow = icrs
7264 End If
7265 End Do
7266 !
7267 jhig = jhig + 1
7268 ihigt(jhig) = ilowt(ilow)
7269 Exit
7270 !
7271 !
7272 Case (0)
7273 !
7274 ! Low part is exactly what we want
7275 !
7276 Exit
7277 ! ---
7278 !
7279 Case (-5 : -1)
7280 !
7281 ! Only few values too many in high part
7282 !
7283 irngt(1) = ihigt(1)
7284 Do icrs = 2, nord
7285 iwrk = ihigt(icrs)
7286 xwrk = xdont(iwrk)
7287 Do idcr = icrs - 1, 1, - 1
7288 If (xwrk > xdont(irngt(idcr))) Then
7289 irngt(idcr + 1) = irngt(idcr)
7290 Else
7291 Exit
7292 End If
7293 End Do
7294 irngt(idcr + 1) = iwrk
7295 End Do
7296 !
7297 xwrk1 = xdont(irngt(nord))
7298 Do icrs = nord + 1, jhig
7299 If (xdont(ihigt(icrs)) > xwrk1) Then
7300 xwrk = xdont(ihigt(icrs))
7301 Do idcr = nord - 1, 1, - 1
7302 If (xwrk <= xdont(irngt(idcr))) Exit
7303 irngt(idcr + 1) = irngt(idcr)
7304 End Do
7305 irngt(idcr + 1) = ihigt(icrs)
7306 xwrk1 = xdont(irngt(nord))
7307 End If
7308 End Do
7309 !
7310 Return
7311 !
7312 !
7313 Case (: -6)
7314 !
7315 ! last case: too many values in high part
7316 ! ---
7317 ideb = jdeb + 1
7318 imil = (jhig + ideb) / 2
7319 ifin = jhig
7320 ! ---
7321 ! One chooses a pivot from 1st, last, and middle values
7322 !
7323 If (xdont(ihigt(imil)) > xdont(ihigt(ideb))) Then
7324 iwrk = ihigt(ideb)
7325 ihigt(ideb) = ihigt(imil)
7326 ihigt(imil) = iwrk
7327 End If
7328 If (xdont(ihigt(imil)) < xdont(ihigt(ifin))) Then
7329 iwrk = ihigt(ifin)
7330 ihigt(ifin) = ihigt(imil)
7331 ihigt(imil) = iwrk
7332 If (xdont(ihigt(imil)) > xdont(ihigt(ideb))) Then
7333 iwrk = ihigt(ideb)
7334 ihigt(ideb) = ihigt(imil)
7335 ihigt(imil) = iwrk
7336 End If
7337 End If
7338 If (ifin <= 3) Exit
7339 ! ---
7340 xpiv = xdont(ihigt(1)) + real(nord, sp) / real(jhig + nord, sp) * &
7341 (xdont(ihigt(ifin)) - xdont(ihigt(1)))
7342 If (jdeb > 0) Then
7343 If (xpiv <= xpiv0) &
7344 xpiv = xpiv0 + real(2 * nord - jdeb, dp) / real(jhig + nord, dp) * &
7345 (xdont(ihigt(ifin)) - xpiv0)
7346 Else
7347 ideb = 1
7348 End If
7349 !
7350 ! One takes values < XPIV to ILOWT
7351 ! However, we do not process the first values if we have been
7352 ! through the case when we did not have enough high values
7353 ! ---
7354 jlow = 0
7355 jhig = jdeb
7356 ! ---
7357 If (xdont(ihigt(ifin)) < xpiv) Then
7358 icrs = jdeb
7359 Do
7360 icrs = icrs + 1
7361 If (xdont(ihigt(icrs)) < xpiv) Then
7362 jlow = jlow + 1
7363 ilowt(jlow) = ihigt(icrs)
7364 If (icrs >= ifin) Exit
7365 Else
7366 jhig = jhig + 1
7367 ihigt(jhig) = ihigt(icrs)
7368 If (jhig >= nord) Exit
7369 End If
7370 End Do
7371 ! ---
7372 If (icrs < ifin) Then
7373 Do
7374 icrs = icrs + 1
7375 If (xdont(ihigt(icrs)) >= xpiv) Then
7376 jhig = jhig + 1
7377 ihigt(jhig) = ihigt(icrs)
7378 Else
7379 If (icrs >= ifin) Exit
7380 End If
7381 End Do
7382 End If
7383 Else
7384 Do icrs = ideb, ifin
7385 If (xdont(ihigt(icrs)) < xpiv) Then
7386 jlow = jlow + 1
7387 ilowt(jlow) = ihigt(icrs)
7388 Else
7389 jhig = jhig + 1
7390 ihigt(jhig) = ihigt(icrs)
7391 If (jhig >= nord) Exit
7392 End If
7393 End Do
7394 !
7395 Do icrs = icrs + 1, ifin
7396 If (xdont(ihigt(icrs)) >= xpiv) Then
7397 jhig = jhig + 1
7398 ihigt(jhig) = ihigt(icrs)
7399 End If
7400 End Do
7401 End If
7402 !
7403 End Select
7404 !
7405 End Do
7406 ! ---
7407 ! Now, we only need to complete ranking of the 1:NORD set
7408 ! Assuming NORD is small, we use a simple insertion sort
7409 !
7410 irngt(1) = ihigt(1)
7411 Do icrs = 2, nord
7412 iwrk = ihigt(icrs)
7413 xwrk = xdont(iwrk)
7414 Do idcr = icrs - 1, 1, - 1
7415 If (xwrk > xdont(irngt(idcr))) Then
7416 irngt(idcr + 1) = irngt(idcr)
7417 Else
7418 Exit
7419 End If
7420 End Do
7421 irngt(idcr + 1) = iwrk
7422 End Do
7423 Return
7424 !
7425 !
7426 End Subroutine d_rapknr
7427
7428 Subroutine r_rapknr (XDONT, IRNGT, NORD)
7429 ! Ranks partially XDONT by IRNGT, up to order NORD, in decreasing order.
7430 ! rapknr = (rnkpar backwards)
7431 ! __________________________________________________________
7432 ! This routine uses a pivoting strategy such as the one of
7433 ! finding the median based on the quicksort algorithm, but
7434 ! we skew the pivot choice to try to bring it to NORD as
7435 ! fast as possible. It uses 2 temporary arrays, where it
7436 ! stores the indices of the values larger than the pivot
7437 ! (IHIGT), and the indices of values smaller than the pivot
7438 ! that we might still need later on (ILOWT). It iterates
7439 ! until it can bring the number of values in IHIGT to
7440 ! exactly NORD, and then uses an insertion sort to rank
7441 ! this set, since it is supposedly small.
7442 ! Michel Olagnon - Feb. 2011
7443 ! __________________________________________________________
7444 ! __________________________________________________________
7445 ! _________________________________________________________
7446 Real(kind = sp), Dimension (:), Intent (In) :: xdont
7447 Integer(kind = i4), Dimension (:), Intent (Out) :: IRNGT
7448 Integer(kind = i4), Intent (In) :: NORD
7449 ! __________________________________________________________
7450 Real(kind = sp) :: xpiv, xpiv0, xwrk, xwrk1, xmin, xmax
7451 !
7452 Integer(kind = i4), Dimension (SIZE(XDONT)) :: ILOWT, IHIGT
7453 Integer(kind = i4) :: NDON, JHIG, JLOW, IHIG, IWRK, IWRK1, IWRK2, IWRK3
7454 Integer(kind = i4) :: IDEB, JDEB, IMIL, IFIN, NWRK, ICRS, IDCR, ILOW
7455 Integer(kind = i4) :: JLM2, JLM1, JHM2, JHM1
7456 !
7457 ndon = SIZE (xdont)
7458 !
7459 ! First loop is used to fill-in ILOWT, IHIGT at the same time
7460 !
7461 If (ndon < 2) Then
7462 If (nord >= 1) irngt(1) = 1
7463 Return
7464 End If
7465 !
7466 ! One chooses a pivot, best estimate possible to put fractile near
7467 ! mid-point of the set of high values.
7468 !
7469 If (xdont(2) < xdont(1)) Then
7470 ilowt(1) = 2
7471 ihigt(1) = 1
7472 Else
7473 ilowt(1) = 1
7474 ihigt(1) = 2
7475 End If
7476 !
7477 If (ndon < 3) Then
7478 If (nord >= 1) irngt(1) = ihigt(1)
7479 If (nord >= 2) irngt(2) = ilowt(1)
7480 Return
7481 End If
7482 ! ---
7483 If (xdont(3) > xdont(ilowt(1))) Then
7484 ilowt(2) = ilowt(1)
7485 If (xdont(3) > xdont(ihigt(1))) Then
7486 ilowt(1) = ihigt(1)
7487 ihigt(1) = 3
7488 Else
7489 ilowt(1) = 3
7490 End If
7491 Else
7492 ilowt(2) = 3
7493 End If
7494 ! ---
7495 If (ndon < 4) Then
7496 If (nord >= 1) irngt(1) = ihigt(1)
7497 If (nord >= 2) irngt(2) = ilowt(1)
7498 If (nord >= 3) irngt(3) = ilowt(2)
7499 Return
7500 End If
7501 !
7502 If (xdont(ndon) > xdont(ilowt(1))) Then
7503 ilowt(3) = ilowt(2)
7504 ilowt(2) = ilowt(1)
7505 If (xdont(ndon) > xdont(ihigt(1))) Then
7506 ilowt(1) = ihigt(1)
7507 ihigt(1) = ndon
7508 Else
7509 ilowt(1) = ndon
7510 End If
7511 Else
7512 if (xdont(ndon) > xdont(ilowt(2))) Then
7513 ilowt(3) = ilowt(2)
7514 ilowt(2) = ndon
7515 else
7516 ilowt(3) = ndon
7517 end if
7518 End If
7519 !
7520 If (ndon < 5) Then
7521 If (nord >= 1) irngt(1) = ihigt(1)
7522 If (nord >= 2) irngt(2) = ilowt(1)
7523 If (nord >= 3) irngt(3) = ilowt(2)
7524 If (nord >= 4) irngt(4) = ilowt(3)
7525 Return
7526 End If
7527 ! ---
7528 jdeb = 0
7529 ideb = jdeb + 1
7530 jhig = ideb
7531 jlow = 3
7532 xpiv = xdont(ihigt(ideb)) + real(2 * nord, sp) / real(ndon + nord, sp) * &
7533 (xdont(ilowt(3)) - xdont(ihigt(ideb)))
7534 If (xpiv >= xdont(ilowt(1))) Then
7535 xpiv = xdont(ihigt(ideb)) + real(2 * nord, sp) / real(ndon + nord, sp) * &
7536 (xdont(ilowt(2)) - xdont(ihigt(ideb)))
7537 If (xpiv >= xdont(ilowt(1))) &
7538 xpiv = xdont(ihigt(ideb)) + real(2 * nord, sp) / real(ndon + nord, sp) * &
7539 (xdont(ilowt(1)) - xdont(ihigt(ideb)))
7540 End If
7541 xpiv0 = xpiv
7542 ! ---
7543 ! One puts values < pivot in the end and those >= pivot
7544 ! at the beginning. This is split in 2 cases, so that
7545 ! we can skip the loop test a number of times.
7546 ! As we are also filling in the work arrays at the same time
7547 ! we stop filling in the ILOWT array as soon as we have more
7548 ! than enough values in IHIGT.
7549 !
7550 !
7551 If (xdont(ndon) < xpiv) Then
7552 icrs = 3
7553 Do
7554 icrs = icrs + 1
7555 If (xdont(icrs) < xpiv) Then
7556 If (icrs >= ndon) Exit
7557 jlow = jlow + 1
7558 ilowt(jlow) = icrs
7559 Else
7560 jhig = jhig + 1
7561 ihigt(jhig) = icrs
7562 If (jhig >= nord) Exit
7563 End If
7564 End Do
7565 !
7566 ! One restricts further processing because it is no use
7567 ! to store more low values
7568 !
7569 If (icrs < ndon - 1) Then
7570 Do
7571 icrs = icrs + 1
7572 If (xdont(icrs) >= xpiv) Then
7573 jhig = jhig + 1
7574 ihigt(jhig) = icrs
7575 Else If (icrs >= ndon) Then
7576 Exit
7577 End If
7578 End Do
7579 End If
7580 !
7581 ! ---
7582 Else
7583 !
7584 ! Same as above, but this is not as easy to optimize, so the
7585 ! DO-loop is kept
7586 !
7587 Do icrs = 4, ndon - 1
7588 If (xdont(icrs) < xpiv) Then
7589 jlow = jlow + 1
7590 ilowt(jlow) = icrs
7591 Else
7592 jhig = jhig + 1
7593 ihigt(jhig) = icrs
7594 If (jhig >= nord) Exit
7595 End If
7596 End Do
7597 !
7598 If (icrs < ndon - 1) Then
7599 Do
7600 icrs = icrs + 1
7601 If (xdont(icrs) >= xpiv) Then
7602 If (icrs >= ndon) Exit
7603 jhig = jhig + 1
7604 ihigt(jhig) = icrs
7605 End If
7606 End Do
7607 End If
7608 End If
7609 ! ---
7610 jlm2 = 0
7611 jlm1 = 0
7612 jhm2 = 0
7613 jhm1 = 0
7614 Do
7615 if (jhig == nord) Exit
7616 If (jhm2 == jhig .And. jlm2 == jlow) Then
7617 !
7618 ! We are oscillating. Perturbate by bringing JHIG closer by one
7619 ! to NORD
7620 !
7621 If (nord > jhig) Then
7622 xmax = xdont(ilowt(1))
7623 ilow = 1
7624 Do icrs = 2, jlow
7625 If (xdont(ilowt(icrs)) > xmax) Then
7626 xmax = xdont(ilowt(icrs))
7627 ilow = icrs
7628 End If
7629 End Do
7630 !
7631 jhig = jhig + 1
7632 ihigt(jhig) = ilowt(ilow)
7633 ilowt(ilow) = ilowt(jlow)
7634 jlow = jlow - 1
7635 Else
7636 ihig = ihigt(jhig)
7637 xmin = xdont(ihig)
7638 Do icrs = 1, jhig
7639 If (xdont(ihigt(icrs)) < xmin) Then
7640 iwrk = ihigt(icrs)
7641 xmin = xdont(iwrk)
7642 ihigt(icrs) = ihig
7643 ihig = iwrk
7644 End If
7645 End Do
7646 jhig = jhig - 1
7647 End If
7648 End If
7649 jlm2 = jlm1
7650 jlm1 = jlow
7651 jhm2 = jhm1
7652 jhm1 = jhig
7653 ! ---
7654 ! We try to bring the number of values in the high values set
7655 ! closer to NORD.
7656 !
7657 Select Case (nord - jhig)
7658 Case (2 :)
7659 !
7660 ! Not enough values in low part, at least 2 are missing
7661 !
7662 Select Case (jlow)
7663 !!!!! CASE DEFAULT
7664 !!!!! write (*,*) "Assertion failed"
7665 !!!!! STOP
7666 !
7667 ! We make a special case when we have so few values in
7668 ! the low values set that it is bad performance to choose a pivot
7669 ! and apply the general algorithm.
7670 !
7671 Case (2)
7672 If (xdont(ilowt(1)) >= xdont(ilowt(2))) Then
7673 jhig = jhig + 1
7674 ihigt(jhig) = ilowt(1)
7675 jhig = jhig + 1
7676 ihigt(jhig) = ilowt(2)
7677 Else
7678 jhig = jhig + 1
7679 ihigt(jhig) = ilowt(2)
7680 jhig = jhig + 1
7681 ihigt(jhig) = ilowt(1)
7682 End If
7683 Exit
7684 ! ---
7685 Case (3)
7686 !
7687 !
7688 iwrk1 = ilowt(1)
7689 iwrk2 = ilowt(2)
7690 iwrk3 = ilowt(3)
7691 If (xdont(iwrk2) > xdont(iwrk1)) Then
7692 ilowt(1) = iwrk2
7693 ilowt(2) = iwrk1
7694 iwrk2 = iwrk1
7695 End If
7696 If (xdont(iwrk2) < xdont(iwrk3)) Then
7697 ilowt(3) = iwrk2
7698 ilowt(2) = iwrk3
7699 iwrk2 = iwrk3
7700 If (xdont(iwrk2) > xdont(ilowt(1))) Then
7701 ilowt(2) = ilowt(1)
7702 ilowt(1) = iwrk2
7703 End If
7704 End If
7705 jlow = 0
7706 Do icrs = jhig + 1, nord
7707 jlow = jlow + 1
7708 ihigt(icrs) = ilowt(jlow)
7709 End Do
7710 jhig = nord
7711 Exit
7712 ! ---
7713 Case (4 :)
7714 !
7715 !
7716 xpiv0 = xpiv
7717 ifin = jlow
7718 !
7719 ! One chooses a pivot from the 2 first values and the last one.
7720 ! This should ensure sufficient renewal between iterations to
7721 ! avoid worst case behavior effects.
7722 !
7723 iwrk1 = ilowt(1)
7724 iwrk2 = ilowt(2)
7725 iwrk3 = ilowt(ifin)
7726 If (xdont(iwrk2) > xdont(iwrk1)) Then
7727 ilowt(1) = iwrk2
7728 ilowt(2) = iwrk1
7729 iwrk2 = iwrk1
7730 End If
7731 If (xdont(iwrk2) < xdont(iwrk3)) Then
7732 ilowt(ifin) = iwrk2
7733 ilowt(2) = iwrk3
7734 iwrk2 = iwrk3
7735 If (xdont(iwrk2) > xdont(ihigt(1))) Then
7736 ilowt(2) = ilowt(1)
7737 ilowt(1) = iwrk2
7738 End If
7739 End If
7740 !
7741 jdeb = jhig
7742 nwrk = nord - jhig
7743 iwrk1 = ilowt(1)
7744 jhig = jhig + 1
7745 ihigt(jhig) = iwrk1
7746 xpiv = xdont(iwrk1) + real(nwrk, sp) / real(nord + nwrk, sp) * &
7747 (xdont(ilowt(ifin)) - xdont(iwrk1))
7748 !
7749 ! One takes values >= pivot to IHIGT
7750 ! Again, 2 parts, one where we take care of the remaining
7751 ! low values because we might still need them, and the
7752 ! other when we know that we will have more than enough
7753 ! high values in the end.
7754 ! ---
7755 jlow = 0
7756 Do icrs = 2, ifin
7757 If (xdont(ilowt(icrs)) >= xpiv) Then
7758 jhig = jhig + 1
7759 ihigt(jhig) = ilowt(icrs)
7760 If (jhig >= nord) Exit
7761 Else
7762 jlow = jlow + 1
7763 ilowt(jlow) = ilowt(icrs)
7764 End If
7765 End Do
7766 !
7767 Do icrs = icrs + 1, ifin
7768 If (xdont(ilowt(icrs)) >= xpiv) Then
7769 jhig = jhig + 1
7770 ihigt(jhig) = ilowt(icrs)
7771 End If
7772 End Do
7773 End Select
7774 ! ---
7775 !
7776 Case (1)
7777 !
7778 ! Only 1 value is missing in high part
7779 !
7780 xmax = xdont(ilowt(1))
7781 ilow = 1
7782 Do icrs = 2, jlow
7783 If (xdont(ilowt(icrs)) > xmax) Then
7784 xmax = xdont(ilowt(icrs))
7785 ilow = icrs
7786 End If
7787 End Do
7788 !
7789 jhig = jhig + 1
7790 ihigt(jhig) = ilowt(ilow)
7791 Exit
7792 !
7793 !
7794 Case (0)
7795 !
7796 ! Low part is exactly what we want
7797 !
7798 Exit
7799 ! ---
7800 !
7801 Case (-5 : -1)
7802 !
7803 ! Only few values too many in high part
7804 !
7805 irngt(1) = ihigt(1)
7806 Do icrs = 2, nord
7807 iwrk = ihigt(icrs)
7808 xwrk = xdont(iwrk)
7809 Do idcr = icrs - 1, 1, - 1
7810 If (xwrk > xdont(irngt(idcr))) Then
7811 irngt(idcr + 1) = irngt(idcr)
7812 Else
7813 Exit
7814 End If
7815 End Do
7816 irngt(idcr + 1) = iwrk
7817 End Do
7818 !
7819 xwrk1 = xdont(irngt(nord))
7820 Do icrs = nord + 1, jhig
7821 If (xdont(ihigt(icrs)) > xwrk1) Then
7822 xwrk = xdont(ihigt(icrs))
7823 Do idcr = nord - 1, 1, - 1
7824 If (xwrk <= xdont(irngt(idcr))) Exit
7825 irngt(idcr + 1) = irngt(idcr)
7826 End Do
7827 irngt(idcr + 1) = ihigt(icrs)
7828 xwrk1 = xdont(irngt(nord))
7829 End If
7830 End Do
7831 !
7832 Return
7833 !
7834 !
7835 Case (: -6)
7836 !
7837 ! last case: too many values in high part
7838 ! ---
7839 ideb = jdeb + 1
7840 imil = (jhig + ideb) / 2
7841 ifin = jhig
7842 ! ---
7843 ! One chooses a pivot from 1st, last, and middle values
7844 !
7845 If (xdont(ihigt(imil)) > xdont(ihigt(ideb))) Then
7846 iwrk = ihigt(ideb)
7847 ihigt(ideb) = ihigt(imil)
7848 ihigt(imil) = iwrk
7849 End If
7850 If (xdont(ihigt(imil)) < xdont(ihigt(ifin))) Then
7851 iwrk = ihigt(ifin)
7852 ihigt(ifin) = ihigt(imil)
7853 ihigt(imil) = iwrk
7854 If (xdont(ihigt(imil)) > xdont(ihigt(ideb))) Then
7855 iwrk = ihigt(ideb)
7856 ihigt(ideb) = ihigt(imil)
7857 ihigt(imil) = iwrk
7858 End If
7859 End If
7860 If (ifin <= 3) Exit
7861 ! ---
7862 xpiv = xdont(ihigt(1)) + real(nord, sp) / real(jhig + nord, sp) * &
7863 (xdont(ihigt(ifin)) - xdont(ihigt(1)))
7864 If (jdeb > 0) Then
7865 If (xpiv <= xpiv0) &
7866 xpiv = xpiv0 + real(2 * nord - jdeb, sp) / real(jhig + nord, sp) * &
7867 (xdont(ihigt(ifin)) - xpiv0)
7868 Else
7869 ideb = 1
7870 End If
7871 !
7872 ! One takes values < XPIV to ILOWT
7873 ! However, we do not process the first values if we have been
7874 ! through the case when we did not have enough high values
7875 ! ---
7876 jlow = 0
7877 jhig = jdeb
7878 ! ---
7879 If (xdont(ihigt(ifin)) < xpiv) Then
7880 icrs = jdeb
7881 Do
7882 icrs = icrs + 1
7883 If (xdont(ihigt(icrs)) < xpiv) Then
7884 jlow = jlow + 1
7885 ilowt(jlow) = ihigt(icrs)
7886 If (icrs >= ifin) Exit
7887 Else
7888 jhig = jhig + 1
7889 ihigt(jhig) = ihigt(icrs)
7890 If (jhig >= nord) Exit
7891 End If
7892 End Do
7893 ! ---
7894 If (icrs < ifin) Then
7895 Do
7896 icrs = icrs + 1
7897 If (xdont(ihigt(icrs)) >= xpiv) Then
7898 jhig = jhig + 1
7899 ihigt(jhig) = ihigt(icrs)
7900 Else
7901 If (icrs >= ifin) Exit
7902 End If
7903 End Do
7904 End If
7905 Else
7906 Do icrs = ideb, ifin
7907 If (xdont(ihigt(icrs)) < xpiv) Then
7908 jlow = jlow + 1
7909 ilowt(jlow) = ihigt(icrs)
7910 Else
7911 jhig = jhig + 1
7912 ihigt(jhig) = ihigt(icrs)
7913 If (jhig >= nord) Exit
7914 End If
7915 End Do
7916 !
7917 Do icrs = icrs + 1, ifin
7918 If (xdont(ihigt(icrs)) >= xpiv) Then
7919 jhig = jhig + 1
7920 ihigt(jhig) = ihigt(icrs)
7921 End If
7922 End Do
7923 End If
7924 !
7925 End Select
7926 !
7927 End Do
7928 ! ---
7929 ! Now, we only need to complete ranking of the 1:NORD set
7930 ! Assuming NORD is small, we use a simple insertion sort
7931 !
7932 irngt(1) = ihigt(1)
7933 Do icrs = 2, nord
7934 iwrk = ihigt(icrs)
7935 xwrk = xdont(iwrk)
7936 Do idcr = icrs - 1, 1, - 1
7937 If (xwrk > xdont(irngt(idcr))) Then
7938 irngt(idcr + 1) = irngt(idcr)
7939 Else
7940 Exit
7941 End If
7942 End Do
7943 irngt(idcr + 1) = iwrk
7944 End Do
7945 Return
7946 !
7947 !
7948 End Subroutine r_rapknr
7949
7950 Subroutine i_rapknr (XDONT, IRNGT, NORD)
7951 ! Ranks partially XDONT by IRNGT, up to order NORD, in decreasing order.
7952 ! rapknr = (rnkpar backwards)
7953 ! __________________________________________________________
7954 ! This routine uses a pivoting strategy such as the one of
7955 ! finding the median based on the quicksort algorithm, but
7956 ! we skew the pivot choice to try to bring it to NORD as
7957 ! fast as possible. It uses 2 temporary arrays, where it
7958 ! stores the indices of the values larger than the pivot
7959 ! (IHIGT), and the indices of values smaller than the pivot
7960 ! that we might still need later on (ILOWT). It iterates
7961 ! until it can bring the number of values in IHIGT to
7962 ! exactly NORD, and then uses an insertion sort to rank
7963 ! this set, since it is supposedly small.
7964 ! Michel Olagnon - Feb. 2011
7965 ! __________________________________________________________
7966 ! __________________________________________________________
7967 ! __________________________________________________________
7968 Integer(kind = i4), Dimension (:), Intent (In) :: XDONT
7969 Integer(kind = i4), Dimension (:), Intent (Out) :: IRNGT
7970 Integer(kind = i4), Intent (In) :: NORD
7971 ! __________________________________________________________
7972 Integer(kind = i4) :: XPIV, XPIV0, XWRK, XWRK1, XMIN, XMAX
7973 !
7974 Integer(kind = i4), Dimension (SIZE(XDONT)) :: ILOWT, IHIGT
7975 Integer(kind = i4) :: NDON, JHIG, JLOW, IHIG, IWRK, IWRK1, IWRK2, IWRK3
7976 Integer(kind = i4) :: IDEB, JDEB, IMIL, IFIN, NWRK, ICRS, IDCR, ILOW
7977 Integer(kind = i4) :: JLM2, JLM1, JHM2, JHM1
7978 !
7979 ndon = SIZE (xdont)
7980 !
7981 ! First loop is used to fill-in ILOWT, IHIGT at the same time
7982 !
7983 If (ndon < 2) Then
7984 If (nord >= 1) irngt(1) = 1
7985 Return
7986 End If
7987 !
7988 ! One chooses a pivot, best estimate possible to put fractile near
7989 ! mid-point of the set of high values.
7990 !
7991 If (xdont(2) < xdont(1)) Then
7992 ilowt(1) = 2
7993 ihigt(1) = 1
7994 Else
7995 ilowt(1) = 1
7996 ihigt(1) = 2
7997 End If
7998 !
7999 If (ndon < 3) Then
8000 If (nord >= 1) irngt(1) = ihigt(1)
8001 If (nord >= 2) irngt(2) = ilowt(1)
8002 Return
8003 End If
8004 ! ---
8005 If (xdont(3) > xdont(ilowt(1))) Then
8006 ilowt(2) = ilowt(1)
8007 If (xdont(3) > xdont(ihigt(1))) Then
8008 ilowt(1) = ihigt(1)
8009 ihigt(1) = 3
8010 Else
8011 ilowt(1) = 3
8012 End If
8013 Else
8014 ilowt(2) = 3
8015 End If
8016 ! ---
8017 If (ndon < 4) Then
8018 If (nord >= 1) irngt(1) = ihigt(1)
8019 If (nord >= 2) irngt(2) = ilowt(1)
8020 If (nord >= 3) irngt(3) = ilowt(2)
8021 Return
8022 End If
8023 !
8024 If (xdont(ndon) > xdont(ilowt(1))) Then
8025 ilowt(3) = ilowt(2)
8026 ilowt(2) = ilowt(1)
8027 If (xdont(ndon) > xdont(ihigt(1))) Then
8028 ilowt(1) = ihigt(1)
8029 ihigt(1) = ndon
8030 Else
8031 ilowt(1) = ndon
8032 End If
8033 Else
8034 if (xdont(ndon) > xdont(ilowt(2))) Then
8035 ilowt(3) = ilowt(2)
8036 ilowt(2) = ndon
8037 else
8038 ilowt(3) = ndon
8039 end if
8040 End If
8041 !
8042 If (ndon < 5) Then
8043 If (nord >= 1) irngt(1) = ihigt(1)
8044 If (nord >= 2) irngt(2) = ilowt(1)
8045 If (nord >= 3) irngt(3) = ilowt(2)
8046 If (nord >= 4) irngt(4) = ilowt(3)
8047 Return
8048 End If
8049 ! ---
8050 jdeb = 0
8051 ideb = jdeb + 1
8052 jhig = ideb
8053 jlow = 3
8054 xpiv = xdont(ihigt(ideb)) + int(real(2 * nord, sp) / real(ndon + nord, sp), i4) * &
8055 (xdont(ilowt(3)) - xdont(ihigt(ideb)))
8056 If (xpiv >= xdont(ilowt(1))) Then
8057 xpiv = xdont(ihigt(ideb)) + int(real(2 * nord, sp) / real(ndon + nord, sp), i4) * &
8058 (xdont(ilowt(2)) - xdont(ihigt(ideb)))
8059 If (xpiv >= xdont(ilowt(1))) &
8060 xpiv = xdont(ihigt(ideb)) + int(real(2 * nord, sp) / real(ndon + nord, sp), i4) * &
8061 (xdont(ilowt(1)) - xdont(ihigt(ideb)))
8062 End If
8063 xpiv0 = xpiv
8064 ! ---
8065 ! One puts values < pivot in the end and those >= pivot
8066 ! at the beginning. This is split in 2 cases, so that
8067 ! we can skip the loop test a number of times.
8068 ! As we are also filling in the work arrays at the same time
8069 ! we stop filling in the ILOWT array as soon as we have more
8070 ! than enough values in IHIGT.
8071 !
8072 !
8073 If (xdont(ndon) < xpiv) Then
8074 icrs = 3
8075 Do
8076 icrs = icrs + 1
8077 If (xdont(icrs) < xpiv) Then
8078 If (icrs >= ndon) Exit
8079 jlow = jlow + 1
8080 ilowt(jlow) = icrs
8081 Else
8082 jhig = jhig + 1
8083 ihigt(jhig) = icrs
8084 If (jhig >= nord) Exit
8085 End If
8086 End Do
8087 !
8088 ! One restricts further processing because it is no use
8089 ! to store more low values
8090 !
8091 If (icrs < ndon - 1) Then
8092 Do
8093 icrs = icrs + 1
8094 If (xdont(icrs) >= xpiv) Then
8095 jhig = jhig + 1
8096 ihigt(jhig) = icrs
8097 Else If (icrs >= ndon) Then
8098 Exit
8099 End If
8100 End Do
8101 End If
8102 !
8103 ! ---
8104 Else
8105 !
8106 ! Same as above, but this is not as easy to optimize, so the
8107 ! DO-loop is kept
8108 !
8109 Do icrs = 4, ndon - 1
8110 If (xdont(icrs) < xpiv) Then
8111 jlow = jlow + 1
8112 ilowt(jlow) = icrs
8113 Else
8114 jhig = jhig + 1
8115 ihigt(jhig) = icrs
8116 If (jhig >= nord) Exit
8117 End If
8118 End Do
8119 !
8120 If (icrs < ndon - 1) Then
8121 Do
8122 icrs = icrs + 1
8123 If (xdont(icrs) >= xpiv) Then
8124 If (icrs >= ndon) Exit
8125 jhig = jhig + 1
8126 ihigt(jhig) = icrs
8127 End If
8128 End Do
8129 End If
8130 End If
8131 ! ---
8132 jlm2 = 0
8133 jlm1 = 0
8134 jhm2 = 0
8135 jhm1 = 0
8136 Do
8137 if (jhig == nord) Exit
8138 If (jhm2 == jhig .And. jlm2 == jlow) Then
8139 !
8140 ! We are oscillating. Perturbate by bringing JHIG closer by one
8141 ! to NORD
8142 !
8143 If (nord > jhig) Then
8144 xmax = xdont(ilowt(1))
8145 ilow = 1
8146 Do icrs = 2, jlow
8147 If (xdont(ilowt(icrs)) > xmax) Then
8148 xmax = xdont(ilowt(icrs))
8149 ilow = icrs
8150 End If
8151 End Do
8152 !
8153 jhig = jhig + 1
8154 ihigt(jhig) = ilowt(ilow)
8155 ilowt(ilow) = ilowt(jlow)
8156 jlow = jlow - 1
8157 Else
8158 ihig = ihigt(jhig)
8159 xmin = xdont(ihig)
8160 Do icrs = 1, jhig
8161 If (xdont(ihigt(icrs)) < xmin) Then
8162 iwrk = ihigt(icrs)
8163 xmin = xdont(iwrk)
8164 ihigt(icrs) = ihig
8165 ihig = iwrk
8166 End If
8167 End Do
8168 jhig = jhig - 1
8169 End If
8170 End If
8171 jlm2 = jlm1
8172 jlm1 = jlow
8173 jhm2 = jhm1
8174 jhm1 = jhig
8175 ! ---
8176 ! We try to bring the number of values in the high values set
8177 ! closer to NORD.
8178 !
8179 Select Case (nord - jhig)
8180 Case (2 :)
8181 !
8182 ! Not enough values in low part, at least 2 are missing
8183 !
8184 Select Case (jlow)
8185 !!!!! CASE DEFAULT
8186 !!!!! write (*,*) "Assertion failed"
8187 !!!!! STOP
8188 !
8189 ! We make a special case when we have so few values in
8190 ! the low values set that it is bad performance to choose a pivot
8191 ! and apply the general algorithm.
8192 !
8193 Case (2)
8194 If (xdont(ilowt(1)) >= xdont(ilowt(2))) Then
8195 jhig = jhig + 1
8196 ihigt(jhig) = ilowt(1)
8197 jhig = jhig + 1
8198 ihigt(jhig) = ilowt(2)
8199 Else
8200 jhig = jhig + 1
8201 ihigt(jhig) = ilowt(2)
8202 jhig = jhig + 1
8203 ihigt(jhig) = ilowt(1)
8204 End If
8205 Exit
8206 ! ---
8207 Case (3)
8208 !
8209 !
8210 iwrk1 = ilowt(1)
8211 iwrk2 = ilowt(2)
8212 iwrk3 = ilowt(3)
8213 If (xdont(iwrk2) > xdont(iwrk1)) Then
8214 ilowt(1) = iwrk2
8215 ilowt(2) = iwrk1
8216 iwrk2 = iwrk1
8217 End If
8218 If (xdont(iwrk2) < xdont(iwrk3)) Then
8219 ilowt(3) = iwrk2
8220 ilowt(2) = iwrk3
8221 iwrk2 = iwrk3
8222 If (xdont(iwrk2) > xdont(ilowt(1))) Then
8223 ilowt(2) = ilowt(1)
8224 ilowt(1) = iwrk2
8225 End If
8226 End If
8227 jlow = 0
8228 Do icrs = jhig + 1, nord
8229 jlow = jlow + 1
8230 ihigt(icrs) = ilowt(jlow)
8231 End Do
8232 jhig = nord
8233 Exit
8234 ! ---
8235 Case (4 :)
8236 !
8237 !
8238 xpiv0 = xpiv
8239 ifin = jlow
8240 !
8241 ! One chooses a pivot from the 2 first values and the last one.
8242 ! This should ensure sufficient renewal between iterations to
8243 ! avoid worst case behavior effects.
8244 !
8245 iwrk1 = ilowt(1)
8246 iwrk2 = ilowt(2)
8247 iwrk3 = ilowt(ifin)
8248 If (xdont(iwrk2) > xdont(iwrk1)) Then
8249 ilowt(1) = iwrk2
8250 ilowt(2) = iwrk1
8251 iwrk2 = iwrk1
8252 End If
8253 If (xdont(iwrk2) < xdont(iwrk3)) Then
8254 ilowt(ifin) = iwrk2
8255 ilowt(2) = iwrk3
8256 iwrk2 = iwrk3
8257 If (xdont(iwrk2) > xdont(ihigt(1))) Then
8258 ilowt(2) = ilowt(1)
8259 ilowt(1) = iwrk2
8260 End If
8261 End If
8262 !
8263 jdeb = jhig
8264 nwrk = nord - jhig
8265 iwrk1 = ilowt(1)
8266 jhig = jhig + 1
8267 ihigt(jhig) = iwrk1
8268 xpiv = xdont(iwrk1) + int(real(nwrk, sp) / real(nord + nwrk, sp), i4) * &
8269 (xdont(ilowt(ifin)) - xdont(iwrk1))
8270 !
8271 ! One takes values >= pivot to IHIGT
8272 ! Again, 2 parts, one where we take care of the remaining
8273 ! low values because we might still need them, and the
8274 ! other when we know that we will have more than enough
8275 ! high values in the end.
8276 ! ---
8277 jlow = 0
8278 Do icrs = 2, ifin
8279 If (xdont(ilowt(icrs)) >= xpiv) Then
8280 jhig = jhig + 1
8281 ihigt(jhig) = ilowt(icrs)
8282 If (jhig >= nord) Exit
8283 Else
8284 jlow = jlow + 1
8285 ilowt(jlow) = ilowt(icrs)
8286 End If
8287 End Do
8288 !
8289 Do icrs = icrs + 1, ifin
8290 If (xdont(ilowt(icrs)) >= xpiv) Then
8291 jhig = jhig + 1
8292 ihigt(jhig) = ilowt(icrs)
8293 End If
8294 End Do
8295 End Select
8296 ! ---
8297 !
8298 Case (1)
8299 !
8300 ! Only 1 value is missing in high part
8301 !
8302 xmax = xdont(ilowt(1))
8303 ilow = 1
8304 Do icrs = 2, jlow
8305 If (xdont(ilowt(icrs)) > xmax) Then
8306 xmax = xdont(ilowt(icrs))
8307 ilow = icrs
8308 End If
8309 End Do
8310 !
8311 jhig = jhig + 1
8312 ihigt(jhig) = ilowt(ilow)
8313 Exit
8314 !
8315 !
8316 Case (0)
8317 !
8318 ! Low part is exactly what we want
8319 !
8320 Exit
8321 ! ---
8322 !
8323 Case (-5 : -1)
8324 !
8325 ! Only few values too many in high part
8326 !
8327 irngt(1) = ihigt(1)
8328 Do icrs = 2, nord
8329 iwrk = ihigt(icrs)
8330 xwrk = xdont(iwrk)
8331 Do idcr = icrs - 1, 1, - 1
8332 If (xwrk > xdont(irngt(idcr))) Then
8333 irngt(idcr + 1) = irngt(idcr)
8334 Else
8335 Exit
8336 End If
8337 End Do
8338 irngt(idcr + 1) = iwrk
8339 End Do
8340 !
8341 xwrk1 = xdont(irngt(nord))
8342 Do icrs = nord + 1, jhig
8343 If (xdont(ihigt(icrs)) > xwrk1) Then
8344 xwrk = xdont(ihigt(icrs))
8345 Do idcr = nord - 1, 1, - 1
8346 If (xwrk <= xdont(irngt(idcr))) Exit
8347 irngt(idcr + 1) = irngt(idcr)
8348 End Do
8349 irngt(idcr + 1) = ihigt(icrs)
8350 xwrk1 = xdont(irngt(nord))
8351 End If
8352 End Do
8353 !
8354 Return
8355 !
8356 !
8357 Case (: -6)
8358 !
8359 ! last case: too many values in high part
8360 ! ---
8361 ideb = jdeb + 1
8362 imil = (jhig + ideb) / 2
8363 ifin = jhig
8364 ! ---
8365 ! One chooses a pivot from 1st, last, and middle values
8366 !
8367 If (xdont(ihigt(imil)) > xdont(ihigt(ideb))) Then
8368 iwrk = ihigt(ideb)
8369 ihigt(ideb) = ihigt(imil)
8370 ihigt(imil) = iwrk
8371 End If
8372 If (xdont(ihigt(imil)) < xdont(ihigt(ifin))) Then
8373 iwrk = ihigt(ifin)
8374 ihigt(ifin) = ihigt(imil)
8375 ihigt(imil) = iwrk
8376 If (xdont(ihigt(imil)) > xdont(ihigt(ideb))) Then
8377 iwrk = ihigt(ideb)
8378 ihigt(ideb) = ihigt(imil)
8379 ihigt(imil) = iwrk
8380 End If
8381 End If
8382 If (ifin <= 3) Exit
8383 ! ---
8384 xpiv = xdont(ihigt(1)) + int(real(nord, sp) / real(jhig + nord, sp), i4) * &
8385 (xdont(ihigt(ifin)) - xdont(ihigt(1)))
8386 If (jdeb > 0) Then
8387 If (xpiv <= xpiv0) &
8388 xpiv = xpiv0 + int(real(2 * nord - jdeb, sp) / real(jhig + nord, sp), i4) * &
8389 (xdont(ihigt(ifin)) - xpiv0)
8390 Else
8391 ideb = 1
8392 End If
8393 !
8394 ! One takes values < XPIV to ILOWT
8395 ! However, we do not process the first values if we have been
8396 ! through the case when we did not have enough high values
8397 ! ---
8398 jlow = 0
8399 jhig = jdeb
8400 ! ---
8401 If (xdont(ihigt(ifin)) < xpiv) Then
8402 icrs = jdeb
8403 Do
8404 icrs = icrs + 1
8405 If (xdont(ihigt(icrs)) < xpiv) Then
8406 jlow = jlow + 1
8407 ilowt(jlow) = ihigt(icrs)
8408 If (icrs >= ifin) Exit
8409 Else
8410 jhig = jhig + 1
8411 ihigt(jhig) = ihigt(icrs)
8412 If (jhig >= nord) Exit
8413 End If
8414 End Do
8415 ! ---
8416 If (icrs < ifin) Then
8417 Do
8418 icrs = icrs + 1
8419 If (xdont(ihigt(icrs)) >= xpiv) Then
8420 jhig = jhig + 1
8421 ihigt(jhig) = ihigt(icrs)
8422 Else
8423 If (icrs >= ifin) Exit
8424 End If
8425 End Do
8426 End If
8427 Else
8428 Do icrs = ideb, ifin
8429 If (xdont(ihigt(icrs)) < xpiv) Then
8430 jlow = jlow + 1
8431 ilowt(jlow) = ihigt(icrs)
8432 Else
8433 jhig = jhig + 1
8434 ihigt(jhig) = ihigt(icrs)
8435 If (jhig >= nord) Exit
8436 End If
8437 End Do
8438 !
8439 Do icrs = icrs + 1, ifin
8440 If (xdont(ihigt(icrs)) >= xpiv) Then
8441 jhig = jhig + 1
8442 ihigt(jhig) = ihigt(icrs)
8443 End If
8444 End Do
8445 End If
8446 !
8447 End Select
8448 !
8449 End Do
8450 ! ---
8451 ! Now, we only need to complete ranking of the 1:NORD set
8452 ! Assuming NORD is small, we use a simple insertion sort
8453 !
8454 irngt(1) = ihigt(1)
8455 Do icrs = 2, nord
8456 iwrk = ihigt(icrs)
8457 xwrk = xdont(iwrk)
8458 Do idcr = icrs - 1, 1, - 1
8459 If (xwrk > xdont(irngt(idcr))) Then
8460 irngt(idcr + 1) = irngt(idcr)
8461 Else
8462 Exit
8463 End If
8464 End Do
8465 irngt(idcr + 1) = iwrk
8466 End Do
8467 Return
8468 !
8469 !
8470 End Subroutine i_rapknr
8471
8472 Subroutine d_refpar (XDONT, IRNGT, NORD)
8473 ! Ranks partially XDONT by IRNGT, up to order NORD
8474 ! __________________________________________________________
8475 ! This routine uses a pivoting strategy such as the one of
8476 ! finding the median based on the quicksort algorithm. It uses
8477 ! a temporary array, where it stores the partially ranked indices
8478 ! of the values. It iterates until it can bring the number of
8479 ! values lower than the pivot to exactly NORD, and then uses an
8480 ! insertion sort to rank this set, since it is supposedly small.
8481 ! Michel Olagnon - Feb. 2000
8482 ! __________________________________________________________
8483 ! __________________________________________________________
8484 real(kind = dp), Dimension (:), Intent (In) :: xdont
8485 Integer(kind = i4), Dimension (:), Intent (Out) :: IRNGT
8486 Integer(kind = i4), Intent (In) :: NORD
8487 ! __________________________________________________________
8488 real(kind = dp) :: xpiv, xwrk
8489 ! __________________________________________________________
8490 !
8491 Integer(kind = i4), Dimension (SIZE(XDONT)) :: IWRKT
8492 Integer(kind = i4) :: NDON, ICRS, IDEB, IDCR, IFIN, IMIL, IWRK
8493 !
8494 ndon = SIZE (xdont)
8495 !
8496 Do icrs = 1, ndon
8497 iwrkt(icrs) = icrs
8498 End Do
8499 ideb = 1
8500 ifin = ndon
8501 Do
8502 If (ideb >= ifin) Exit
8503 imil = (ideb + ifin) / 2
8504 !
8505 ! One chooses a pivot, median of 1st, last, and middle values
8506 !
8507 If (xdont(iwrkt(imil)) < xdont(iwrkt(ideb))) Then
8508 iwrk = iwrkt(ideb)
8509 iwrkt(ideb) = iwrkt(imil)
8510 iwrkt(imil) = iwrk
8511 End If
8512 If (xdont(iwrkt(imil)) > xdont(iwrkt(ifin))) Then
8513 iwrk = iwrkt(ifin)
8514 iwrkt(ifin) = iwrkt(imil)
8515 iwrkt(imil) = iwrk
8516 If (xdont(iwrkt(imil)) < xdont(iwrkt(ideb))) Then
8517 iwrk = iwrkt(ideb)
8518 iwrkt(ideb) = iwrkt(imil)
8519 iwrkt(imil) = iwrk
8520 End If
8521 End If
8522 If ((ifin - ideb) < 3) Exit
8523 xpiv = xdont(iwrkt(imil))
8524 !
8525 ! One exchanges values to put those > pivot in the end and
8526 ! those <= pivot at the beginning
8527 !
8528 icrs = ideb
8529 idcr = ifin
8530 ech2 : Do
8531 Do
8532 icrs = icrs + 1
8533 If (icrs >= idcr) Then
8534 !
8535 ! the first > pivot is IWRKT(IDCR)
8536 ! the last <= pivot is IWRKT(ICRS-1)
8537 ! Note: If one arrives here on the first iteration, then
8538 ! the pivot is the maximum of the set, the last value is equal
8539 ! to it, and one can reduce by one the size of the set to process,
8540 ! as if XDONT (IWRKT(IFIN)) > XPIV
8541 !
8542 Exit ech2
8543 !
8544 End If
8545 If (xdont(iwrkt(icrs)) > xpiv) Exit
8546 End Do
8547 Do
8548 If (xdont(iwrkt(idcr)) <= xpiv) Exit
8549 idcr = idcr - 1
8550 If (icrs >= idcr) Then
8551 !
8552 ! The last value < pivot is always IWRKT(ICRS-1)
8553 !
8554 Exit ech2
8555 End If
8556 End Do
8557 !
8558 iwrk = iwrkt(idcr)
8559 iwrkt(idcr) = iwrkt(icrs)
8560 iwrkt(icrs) = iwrk
8561 End Do ech2
8562 !
8563 ! One restricts further processing to find the fractile value
8564 !
8565 If (icrs <= nord) ideb = icrs
8566 If (icrs > nord) ifin = icrs - 1
8567 End Do
8568 !
8569 ! Now, we only need to complete ranking of the 1:NORD set
8570 ! Assuming NORD is small, we use a simple insertion sort
8571 !
8572 Do icrs = 2, nord
8573 iwrk = iwrkt(icrs)
8574 xwrk = xdont(iwrk)
8575 Do idcr = icrs - 1, 1, - 1
8576 If (xwrk <= xdont(iwrkt(idcr))) Then
8577 iwrkt(idcr + 1) = iwrkt(idcr)
8578 Else
8579 Exit
8580 End If
8581 End Do
8582 iwrkt(idcr + 1) = iwrk
8583 End Do
8584 irngt(1 : nord) = iwrkt(1 : nord)
8585 Return
8586 !
8587 End Subroutine d_refpar
8588
8589 Subroutine r_refpar (XDONT, IRNGT, NORD)
8590 ! Ranks partially XDONT by IRNGT, up to order NORD
8591 ! __________________________________________________________
8592 ! This routine uses a pivoting strategy such as the one of
8593 ! finding the median based on the quicksort algorithm. It uses
8594 ! a temporary array, where it stores the partially ranked indices
8595 ! of the values. It iterates until it can bring the number of
8596 ! values lower than the pivot to exactly NORD, and then uses an
8597 ! insertion sort to rank this set, since it is supposedly small.
8598 ! Michel Olagnon - Feb. 2000
8599 ! __________________________________________________________
8600 ! _________________________________________________________
8601 Real(kind = sp), Dimension (:), Intent (In) :: xdont
8602 Integer(kind = i4), Dimension (:), Intent (Out) :: IRNGT
8603 Integer(kind = i4), Intent (In) :: NORD
8604 ! __________________________________________________________
8605 Real(kind = sp) :: xpiv, xwrk
8606 ! __________________________________________________________
8607 !
8608 Integer(kind = i4), Dimension (SIZE(XDONT)) :: IWRKT
8609 Integer(kind = i4) :: NDON, ICRS, IDEB, IDCR, IFIN, IMIL, IWRK
8610 !
8611 ndon = SIZE (xdont)
8612 !
8613 Do icrs = 1, ndon
8614 iwrkt(icrs) = icrs
8615 End Do
8616 ideb = 1
8617 ifin = ndon
8618 Do
8619 If (ideb >= ifin) Exit
8620 imil = (ideb + ifin) / 2
8621 !
8622 ! One chooses a pivot, median of 1st, last, and middle values
8623 !
8624 If (xdont(iwrkt(imil)) < xdont(iwrkt(ideb))) Then
8625 iwrk = iwrkt(ideb)
8626 iwrkt(ideb) = iwrkt(imil)
8627 iwrkt(imil) = iwrk
8628 End If
8629 If (xdont(iwrkt(imil)) > xdont(iwrkt(ifin))) Then
8630 iwrk = iwrkt(ifin)
8631 iwrkt(ifin) = iwrkt(imil)
8632 iwrkt(imil) = iwrk
8633 If (xdont(iwrkt(imil)) < xdont(iwrkt(ideb))) Then
8634 iwrk = iwrkt(ideb)
8635 iwrkt(ideb) = iwrkt(imil)
8636 iwrkt(imil) = iwrk
8637 End If
8638 End If
8639 If ((ifin - ideb) < 3) Exit
8640 xpiv = xdont(iwrkt(imil))
8641 !
8642 ! One exchanges values to put those > pivot in the end and
8643 ! those <= pivot at the beginning
8644 !
8645 icrs = ideb
8646 idcr = ifin
8647 ech2 : Do
8648 Do
8649 icrs = icrs + 1
8650 If (icrs >= idcr) Then
8651 !
8652 ! the first > pivot is IWRKT(IDCR)
8653 ! the last <= pivot is IWRKT(ICRS-1)
8654 ! Note: If one arrives here on the first iteration, then
8655 ! the pivot is the maximum of the set, the last value is equal
8656 ! to it, and one can reduce by one the size of the set to process,
8657 ! as if XDONT (IWRKT(IFIN)) > XPIV
8658 !
8659 Exit ech2
8660 !
8661 End If
8662 If (xdont(iwrkt(icrs)) > xpiv) Exit
8663 End Do
8664 Do
8665 If (xdont(iwrkt(idcr)) <= xpiv) Exit
8666 idcr = idcr - 1
8667 If (icrs >= idcr) Then
8668 !
8669 ! The last value < pivot is always IWRKT(ICRS-1)
8670 !
8671 Exit ech2
8672 End If
8673 End Do
8674 !
8675 iwrk = iwrkt(idcr)
8676 iwrkt(idcr) = iwrkt(icrs)
8677 iwrkt(icrs) = iwrk
8678 End Do ech2
8679 !
8680 ! One restricts further processing to find the fractile value
8681 !
8682 If (icrs <= nord) ideb = icrs
8683 If (icrs > nord) ifin = icrs - 1
8684 End Do
8685 !
8686 ! Now, we only need to complete ranking of the 1:NORD set
8687 ! Assuming NORD is small, we use a simple insertion sort
8688 !
8689 Do icrs = 2, nord
8690 iwrk = iwrkt(icrs)
8691 xwrk = xdont(iwrk)
8692 Do idcr = icrs - 1, 1, - 1
8693 If (xwrk <= xdont(iwrkt(idcr))) Then
8694 iwrkt(idcr + 1) = iwrkt(idcr)
8695 Else
8696 Exit
8697 End If
8698 End Do
8699 iwrkt(idcr + 1) = iwrk
8700 End Do
8701 irngt(1 : nord) = iwrkt(1 : nord)
8702 Return
8703 !
8704 End Subroutine r_refpar
8705
8706 Subroutine i_refpar (XDONT, IRNGT, NORD)
8707 ! Ranks partially XDONT by IRNGT, up to order NORD
8708 ! __________________________________________________________
8709 ! This routine uses a pivoting strategy such as the one of
8710 ! finding the median based on the quicksort algorithm. It uses
8711 ! a temporary array, where it stores the partially ranked indices
8712 ! of the values. It iterates until it can bring the number of
8713 ! values lower than the pivot to exactly NORD, and then uses an
8714 ! insertion sort to rank this set, since it is supposedly small.
8715 ! Michel Olagnon - Feb. 2000
8716 ! __________________________________________________________
8717 ! __________________________________________________________
8718 Integer(kind = i4), Dimension (:), Intent (In) :: XDONT
8719 Integer(kind = i4), Dimension (:), Intent (Out) :: IRNGT
8720 Integer(kind = i4), Intent (In) :: NORD
8721 ! __________________________________________________________
8722 Integer(kind = i4) :: XPIV, XWRK
8723 !
8724 Integer(kind = i4), Dimension (SIZE(XDONT)) :: IWRKT
8725 Integer(kind = i4) :: NDON, ICRS, IDEB, IDCR, IFIN, IMIL, IWRK
8726 !
8727 ndon = SIZE (xdont)
8728 !
8729 Do icrs = 1, ndon
8730 iwrkt(icrs) = icrs
8731 End Do
8732 ideb = 1
8733 ifin = ndon
8734 Do
8735 If (ideb >= ifin) Exit
8736 imil = (ideb + ifin) / 2
8737 !
8738 ! One chooses a pivot, median of 1st, last, and middle values
8739 !
8740 If (xdont(iwrkt(imil)) < xdont(iwrkt(ideb))) Then
8741 iwrk = iwrkt(ideb)
8742 iwrkt(ideb) = iwrkt(imil)
8743 iwrkt(imil) = iwrk
8744 End If
8745 If (xdont(iwrkt(imil)) > xdont(iwrkt(ifin))) Then
8746 iwrk = iwrkt(ifin)
8747 iwrkt(ifin) = iwrkt(imil)
8748 iwrkt(imil) = iwrk
8749 If (xdont(iwrkt(imil)) < xdont(iwrkt(ideb))) Then
8750 iwrk = iwrkt(ideb)
8751 iwrkt(ideb) = iwrkt(imil)
8752 iwrkt(imil) = iwrk
8753 End If
8754 End If
8755 If ((ifin - ideb) < 3) Exit
8756 xpiv = xdont(iwrkt(imil))
8757 !
8758 ! One exchanges values to put those > pivot in the end and
8759 ! those <= pivot at the beginning
8760 !
8761 icrs = ideb
8762 idcr = ifin
8763 ech2 : Do
8764 Do
8765 icrs = icrs + 1
8766 If (icrs >= idcr) Then
8767 !
8768 ! the first > pivot is IWRKT(IDCR)
8769 ! the last <= pivot is IWRKT(ICRS-1)
8770 ! Note: If one arrives here on the first iteration, then
8771 ! the pivot is the maximum of the set, the last value is equal
8772 ! to it, and one can reduce by one the size of the set to process,
8773 ! as if XDONT (IWRKT(IFIN)) > XPIV
8774 !
8775 Exit ech2
8776 !
8777 End If
8778 If (xdont(iwrkt(icrs)) > xpiv) Exit
8779 End Do
8780 Do
8781 If (xdont(iwrkt(idcr)) <= xpiv) Exit
8782 idcr = idcr - 1
8783 If (icrs >= idcr) Then
8784 !
8785 ! The last value < pivot is always IWRKT(ICRS-1)
8786 !
8787 Exit ech2
8788 End If
8789 End Do
8790 !
8791 iwrk = iwrkt(idcr)
8792 iwrkt(idcr) = iwrkt(icrs)
8793 iwrkt(icrs) = iwrk
8794 End Do ech2
8795 !
8796 ! One restricts further processing to find the fractile value
8797 !
8798 If (icrs <= nord) ideb = icrs
8799 If (icrs > nord) ifin = icrs - 1
8800 End Do
8801 !
8802 ! Now, we only need to complete ranking of the 1:NORD set
8803 ! Assuming NORD is small, we use a simple insertion sort
8804 !
8805 Do icrs = 2, nord
8806 iwrk = iwrkt(icrs)
8807 xwrk = xdont(iwrk)
8808 Do idcr = icrs - 1, 1, - 1
8809 If (xwrk <= xdont(iwrkt(idcr))) Then
8810 iwrkt(idcr + 1) = iwrkt(idcr)
8811 Else
8812 Exit
8813 End If
8814 End Do
8815 iwrkt(idcr + 1) = iwrk
8816 End Do
8817 irngt(1 : nord) = iwrkt(1 : nord)
8818 Return
8819 !
8820 End Subroutine i_refpar
8821
8822 Subroutine d_refsor (XDONT)
8823 ! Sorts XDONT into ascending order - Quicksort
8824 ! __________________________________________________________
8825 ! Quicksort chooses a "pivot" in the set, and explores the
8826 ! array from both ends, looking for a value > pivot with the
8827 ! increasing index, for a value <= pivot with the decreasing
8828 ! index, and swapping them when it has found one of each.
8829 ! The array is then subdivided in 2 ([3]) subsets:
8830 ! { values <= pivot} {pivot} {values > pivot}
8831 ! One then call recursively the program to sort each subset.
8832 ! When the size of the subarray is small enough, one uses an
8833 ! insertion sort that is faster for very small sets.
8834 ! Michel Olagnon - Apr. 2000
8835 ! __________________________________________________________
8836 ! __________________________________________________________
8837 real(kind = dp), Dimension (:), Intent (InOut) :: xdont
8838 ! __________________________________________________________
8839 !
8840 !
8841 Call d_subsor (xdont, 1, Size (xdont))
8842 Call d_inssor (xdont)
8843 Return
8844 End Subroutine d_refsor
8845
8846 Recursive Subroutine d_subsor (XDONT, IDEB1, IFIN1)
8847 ! Sorts XDONT from IDEB1 to IFIN1
8848 ! __________________________________________________________
8849 Real(kind = dp), dimension (:), Intent (InOut) :: xdont
8850 Integer(kind = i4), Intent (In) :: IDEB1, IFIN1
8851 ! __________________________________________________________
8852 Integer(kind = i4), Parameter :: NINS = 16 ! Max for insertion sort
8853 Integer(kind = i4) :: ICRS, IDEB, IDCR, IFIN, IMIL
8854 Real(kind = dp) :: xpiv, xwrk
8855 !
8856 ideb = ideb1
8857 ifin = ifin1
8858 !
8859 ! If we don't have enough values to make it worth while, we leave
8860 ! them unsorted, and the final insertion sort will take care of them
8861 !
8862 If ((ifin - ideb) > nins) Then
8863 imil = (ideb + ifin) / 2
8864 !
8865 ! One chooses a pivot, median of 1st, last, and middle values
8866 !
8867 If (xdont(imil) < xdont(ideb)) Then
8868 xwrk = xdont(ideb)
8869 xdont(ideb) = xdont(imil)
8870 xdont(imil) = xwrk
8871 End If
8872 If (xdont(imil) > xdont(ifin)) Then
8873 xwrk = xdont(ifin)
8874 xdont(ifin) = xdont(imil)
8875 xdont(imil) = xwrk
8876 If (xdont(imil) < xdont(ideb)) Then
8877 xwrk = xdont(ideb)
8878 xdont(ideb) = xdont(imil)
8879 xdont(imil) = xwrk
8880 End If
8881 End If
8882 xpiv = xdont(imil)
8883 !
8884 ! One exchanges values to put those > pivot in the end and
8885 ! those <= pivot at the beginning
8886 !
8887 icrs = ideb
8888 idcr = ifin
8889 ech2 : Do
8890 Do
8891 icrs = icrs + 1
8892 If (icrs >= idcr) Then
8893 !
8894 ! the first > pivot is IDCR
8895 ! the last <= pivot is ICRS-1
8896 ! Note: If one arrives here on the first iteration, then
8897 ! the pivot is the maximum of the set, the last value is equal
8898 ! to it, and one can reduce by one the size of the set to process,
8899 ! as if XDONT (IFIN) > XPIV
8900 !
8901 Exit ech2
8902 !
8903 End If
8904 If (xdont(icrs) > xpiv) Exit
8905 End Do
8906 Do
8907 If (xdont(idcr) <= xpiv) Exit
8908 idcr = idcr - 1
8909 If (icrs >= idcr) Then
8910 !
8911 ! The last value < pivot is always ICRS-1
8912 !
8913 Exit ech2
8914 End If
8915 End Do
8916 !
8917 xwrk = xdont(idcr)
8918 xdont(idcr) = xdont(icrs)
8919 xdont(icrs) = xwrk
8920 End Do ech2
8921 !
8922 ! One now sorts each of the two sub-intervals
8923 !
8924 Call d_subsor (xdont, ideb1, icrs - 1)
8925 Call d_subsor (xdont, idcr, ifin1)
8926 End If
8927 Return
8928 End Subroutine d_subsor
8929 !
8930 Subroutine r_refsor (XDONT)
8931 ! Sorts XDONT into ascending order - Quicksort
8932 ! __________________________________________________________
8933 ! Quicksort chooses a "pivot" in the set, and explores the
8934 ! array from both ends, looking for a value > pivot with the
8935 ! increasing index, for a value <= pivot with the decreasing
8936 ! index, and swapping them when it has found one of each.
8937 ! The array is then subdivided in 2 ([3]) subsets:
8938 ! { values <= pivot} {pivot} {values > pivot}
8939 ! One then call recursively the program to sort each subset.
8940 ! When the size of the subarray is small enough, one uses an
8941 ! insertion sort that is faster for very small sets.
8942 ! Michel Olagnon - Apr. 2000
8943 ! __________________________________________________________
8944 ! _________________________________________________________
8945 Real(kind = sp), Dimension (:), Intent (InOut) :: xdont
8946 ! __________________________________________________________
8947 !
8948 !
8949 Call r_subsor (xdont, 1, Size (xdont))
8950 Call r_inssor (xdont)
8951 Return
8952 End Subroutine r_refsor
8953
8954 Recursive Subroutine r_subsor (XDONT, IDEB1, IFIN1)
8955 ! Sorts XDONT from IDEB1 to IFIN1
8956 ! __________________________________________________________
8957 Real(kind = sp), dimension (:), Intent (InOut) :: xdont
8958 Integer(kind = i4), Intent (In) :: IDEB1, IFIN1
8959 ! __________________________________________________________
8960 Integer(kind = i4), Parameter :: NINS = 16 ! Max for insertion sort
8961 Integer(kind = i4) :: ICRS, IDEB, IDCR, IFIN, IMIL
8962 Real(kind = sp) :: xpiv, xwrk
8963 !
8964 ideb = ideb1
8965 ifin = ifin1
8966 !
8967 ! If we don't have enough values to make it worth while, we leave
8968 ! them unsorted, and the final insertion sort will take care of them
8969 !
8970 If ((ifin - ideb) > nins) Then
8971 imil = (ideb + ifin) / 2
8972 !
8973 ! One chooses a pivot, median of 1st, last, and middle values
8974 !
8975 If (xdont(imil) < xdont(ideb)) Then
8976 xwrk = xdont(ideb)
8977 xdont(ideb) = xdont(imil)
8978 xdont(imil) = xwrk
8979 End If
8980 If (xdont(imil) > xdont(ifin)) Then
8981 xwrk = xdont(ifin)
8982 xdont(ifin) = xdont(imil)
8983 xdont(imil) = xwrk
8984 If (xdont(imil) < xdont(ideb)) Then
8985 xwrk = xdont(ideb)
8986 xdont(ideb) = xdont(imil)
8987 xdont(imil) = xwrk
8988 End If
8989 End If
8990 xpiv = xdont(imil)
8991 !
8992 ! One exchanges values to put those > pivot in the end and
8993 ! those <= pivot at the beginning
8994 !
8995 icrs = ideb
8996 idcr = ifin
8997 ech2 : Do
8998 Do
8999 icrs = icrs + 1
9000 If (icrs >= idcr) Then
9001 !
9002 ! the first > pivot is IDCR
9003 ! the last <= pivot is ICRS-1
9004 ! Note: If one arrives here on the first iteration, then
9005 ! the pivot is the maximum of the set, the last value is equal
9006 ! to it, and one can reduce by one the size of the set to process,
9007 ! as if XDONT (IFIN) > XPIV
9008 !
9009 Exit ech2
9010 !
9011 End If
9012 If (xdont(icrs) > xpiv) Exit
9013 End Do
9014 Do
9015 If (xdont(idcr) <= xpiv) Exit
9016 idcr = idcr - 1
9017 If (icrs >= idcr) Then
9018 !
9019 ! The last value < pivot is always ICRS-1
9020 !
9021 Exit ech2
9022 End If
9023 End Do
9024 !
9025 xwrk = xdont(idcr)
9026 xdont(idcr) = xdont(icrs)
9027 xdont(icrs) = xwrk
9028 End Do ech2
9029 !
9030 ! One now sorts each of the two sub-intervals
9031 !
9032 Call r_subsor (xdont, ideb1, icrs - 1)
9033 Call r_subsor (xdont, idcr, ifin1)
9034 End If
9035 Return
9036 End Subroutine r_subsor
9037 !
9038 Subroutine i_refsor (XDONT)
9039 ! Sorts XDONT into ascending order - Quicksort
9040 ! __________________________________________________________
9041 ! Quicksort chooses a "pivot" in the set, and explores the
9042 ! array from both ends, looking for a value > pivot with the
9043 ! increasing index, for a value <= pivot with the decreasing
9044 ! index, and swapping them when it has found one of each.
9045 ! The array is then subdivided in 2 ([3]) subsets:
9046 ! { values <= pivot} {pivot} {values > pivot}
9047 ! One then call recursively the program to sort each subset.
9048 ! When the size of the subarray is small enough, one uses an
9049 ! insertion sort that is faster for very small sets.
9050 ! Michel Olagnon - Apr. 2000
9051 ! __________________________________________________________
9052 ! __________________________________________________________
9053 Integer(kind = i4), Dimension (:), Intent (InOut) :: XDONT
9054 ! __________________________________________________________
9055 !
9056 !
9057 Call i_subsor (xdont, 1, Size (xdont))
9058 Call i_inssor (xdont)
9059 Return
9060 End Subroutine i_refsor
9061
9062 Recursive Subroutine i_subsor (XDONT, IDEB1, IFIN1)
9063 ! Sorts XDONT from IDEB1 to IFIN1
9064 ! __________________________________________________________
9065 Integer(kind = i4), dimension (:), Intent (InOut) :: XDONT
9066 Integer(kind = i4), Intent (In) :: IDEB1, IFIN1
9067 ! __________________________________________________________
9068 Integer(kind = i4), Parameter :: NINS = 16 ! Max for insertion sort
9069 Integer(kind = i4) :: ICRS, IDEB, IDCR, IFIN, IMIL
9070 Integer(kind = i4) :: XPIV, XWRK
9071 !
9072 ideb = ideb1
9073 ifin = ifin1
9074 !
9075 ! If we don't have enough values to make it worth while, we leave
9076 ! them unsorted, and the final insertion sort will take care of them
9077 !
9078 If ((ifin - ideb) > nins) Then
9079 imil = (ideb + ifin) / 2
9080 !
9081 ! One chooses a pivot, median of 1st, last, and middle values
9082 !
9083 If (xdont(imil) < xdont(ideb)) Then
9084 xwrk = xdont(ideb)
9085 xdont(ideb) = xdont(imil)
9086 xdont(imil) = xwrk
9087 End If
9088 If (xdont(imil) > xdont(ifin)) Then
9089 xwrk = xdont(ifin)
9090 xdont(ifin) = xdont(imil)
9091 xdont(imil) = xwrk
9092 If (xdont(imil) < xdont(ideb)) Then
9093 xwrk = xdont(ideb)
9094 xdont(ideb) = xdont(imil)
9095 xdont(imil) = xwrk
9096 End If
9097 End If
9098 xpiv = xdont(imil)
9099 !
9100 ! One exchanges values to put those > pivot in the end and
9101 ! those <= pivot at the beginning
9102 !
9103 icrs = ideb
9104 idcr = ifin
9105 ech2 : Do
9106 Do
9107 icrs = icrs + 1
9108 If (icrs >= idcr) Then
9109 !
9110 ! the first > pivot is IDCR
9111 ! the last <= pivot is ICRS-1
9112 ! Note: If one arrives here on the first iteration, then
9113 ! the pivot is the maximum of the set, the last value is equal
9114 ! to it, and one can reduce by one the size of the set to process,
9115 ! as if XDONT (IFIN) > XPIV
9116 !
9117 Exit ech2
9118 !
9119 End If
9120 If (xdont(icrs) > xpiv) Exit
9121 End Do
9122 Do
9123 If (xdont(idcr) <= xpiv) Exit
9124 idcr = idcr - 1
9125 If (icrs >= idcr) Then
9126 !
9127 ! The last value < pivot is always ICRS-1
9128 !
9129 Exit ech2
9130 End If
9131 End Do
9132 !
9133 xwrk = xdont(idcr)
9134 xdont(idcr) = xdont(icrs)
9135 xdont(icrs) = xwrk
9136 End Do ech2
9137 !
9138 ! One now sorts each of the two sub-intervals
9139 !
9140 Call i_subsor (xdont, ideb1, icrs - 1)
9141 Call i_subsor (xdont, idcr, ifin1)
9142 End If
9143 Return
9144 End Subroutine i_subsor
9145
9146 Subroutine c_refsor (XDONT)
9147 ! Sorts XDONT into ascending order - Quicksort
9148 ! __________________________________________________________
9149 ! Quicksort chooses a "pivot" in the set, and explores the
9150 ! array from both ends, looking for a value > pivot with the
9151 ! increasing index, for a value <= pivot with the decreasing
9152 ! index, and swapping them when it has found one of each.
9153 ! The array is then subdivided in 2 ([3]) subsets:
9154 ! { values <= pivot} {pivot} {values > pivot}
9155 ! One then call recursively the program to sort each subset.
9156 ! When the size of the subarray is small enough, one uses an
9157 ! insertion sort that is faster for very small sets.
9158 ! Michel Olagnon - Apr. 2000
9159 ! __________________________________________________________
9160 ! __________________________________________________________
9161 character(*), Dimension (:), Intent (InOut) :: XDONT
9162 ! __________________________________________________________
9163 !
9164 !
9165 Call c_subsor (xdont, 1, Size (xdont))
9166 Call c_inssor (xdont)
9167 Return
9168 End Subroutine c_refsor
9169
9170 Recursive Subroutine c_subsor (XDONT, IDEB1, IFIN1)
9171 ! Sorts XDONT from IDEB1 to IFIN1
9172 ! __________________________________________________________
9173 character(*), dimension (:), Intent (InOut) :: XDONT
9174 Integer(kind = i4), Intent (In) :: IDEB1, IFIN1
9175 ! __________________________________________________________
9176 Integer(kind = i4), Parameter :: NINS = 16 ! Max for insertion sort
9177 Integer(kind = i4) :: ICRS, IDEB, IDCR, IFIN, IMIL
9178 character(len(XDONT)) :: XPIV, XWRK
9179 !
9180 ideb = ideb1
9181 ifin = ifin1
9182 !
9183 ! If we don't have enough values to make it worth while, we leave
9184 ! them unsorted, and the final insertion sort will take care of them
9185 !
9186 If ((ifin - ideb) > nins) Then
9187 imil = (ideb + ifin) / 2
9188 !
9189 ! One chooses a pivot, median of 1st, last, and middle values
9190 !
9191 If (xdont(imil) < xdont(ideb)) Then
9192 xwrk = xdont(ideb)
9193 xdont(ideb) = xdont(imil)
9194 xdont(imil) = xwrk
9195 End If
9196 If (xdont(imil) > xdont(ifin)) Then
9197 xwrk = xdont(ifin)
9198 xdont(ifin) = xdont(imil)
9199 xdont(imil) = xwrk
9200 If (xdont(imil) < xdont(ideb)) Then
9201 xwrk = xdont(ideb)
9202 xdont(ideb) = xdont(imil)
9203 xdont(imil) = xwrk
9204 End If
9205 End If
9206 xpiv = xdont(imil)
9207 !
9208 ! One exchanges values to put those > pivot in the end and
9209 ! those <= pivot at the beginning
9210 !
9211 icrs = ideb
9212 idcr = ifin
9213 ech2 : Do
9214 Do
9215 icrs = icrs + 1
9216 If (icrs >= idcr) Then
9217 !
9218 ! the first > pivot is IDCR
9219 ! the last <= pivot is ICRS-1
9220 ! Note: If one arrives here on the first iteration, then
9221 ! the pivot is the maximum of the set, the last value is equal
9222 ! to it, and one can reduce by one the size of the set to process,
9223 ! as if XDONT (IFIN) > XPIV
9224 !
9225 Exit ech2
9226 !
9227 End If
9228 If (xdont(icrs) > xpiv) Exit
9229 End Do
9230 Do
9231 If (xdont(idcr) <= xpiv) Exit
9232 idcr = idcr - 1
9233 If (icrs >= idcr) Then
9234 !
9235 ! The last value < pivot is always ICRS-1
9236 !
9237 Exit ech2
9238 End If
9239 End Do
9240 !
9241 xwrk = xdont(idcr)
9242 xdont(idcr) = xdont(icrs)
9243 xdont(icrs) = xwrk
9244 End Do ech2
9245 !
9246 ! One now sorts each of the two sub-intervals
9247 !
9248 Call c_subsor (xdont, ideb1, icrs - 1)
9249 Call c_subsor (xdont, idcr, ifin1)
9250 End If
9251 Return
9252 End Subroutine c_subsor
9253 !
9254 Subroutine d_rinpar (XDONT, IRNGT, NORD)
9255 ! Ranks partially XDONT by IRNGT, up to order NORD = size (IRNGT)
9256 ! __________________________________________________________
9257 ! This subroutine uses insertion sort, limiting insertion
9258 ! to the first NORD values. It does not use any work array
9259 ! and is faster when NORD is very small (2-5), but worst case
9260 ! behavior can happen fairly probably (initially inverse sorted)
9261 ! In many cases, the refined quicksort method is faster.
9262 ! Michel Olagnon - Feb. 2000
9263 ! __________________________________________________________
9264 ! __________________________________________________________
9265 real(kind = dp), Dimension (:), Intent (In) :: xdont
9266 Integer(kind = i4), Dimension (:), Intent (Out) :: IRNGT
9267 Integer(kind = i4), Intent (In) :: NORD
9268 ! __________________________________________________________
9269 real(kind = dp) :: xwrk, xwrk1
9270 !
9271 Integer(kind = i4) :: ICRS, IDCR
9272 !
9273 irngt(1) = 1
9274 Do icrs = 2, nord
9275 xwrk = xdont(icrs)
9276 Do idcr = icrs - 1, 1, - 1
9277 If (xwrk >= xdont(irngt(idcr))) Exit
9278 irngt(idcr + 1) = irngt(idcr)
9279 End Do
9280 irngt(idcr + 1) = icrs
9281 End Do
9282 !
9283 xwrk1 = xdont(irngt(nord))
9284 Do icrs = nord + 1, SIZE (xdont)
9285 If (xdont(icrs) < xwrk1) Then
9286 xwrk = xdont(icrs)
9287 Do idcr = nord - 1, 1, - 1
9288 If (xwrk >= xdont(irngt(idcr))) Exit
9289 irngt(idcr + 1) = irngt(idcr)
9290 End Do
9291 irngt(idcr + 1) = icrs
9292 xwrk1 = xdont(irngt(nord))
9293 End If
9294 End Do
9295 !
9296 !
9297 End Subroutine d_rinpar
9298
9299 Subroutine r_rinpar (XDONT, IRNGT, NORD)
9300 ! Ranks partially XDONT by IRNGT, up to order NORD = size (IRNGT)
9301 ! __________________________________________________________
9302 ! This subroutine uses insertion sort, limiting insertion
9303 ! to the first NORD values. It does not use any work array
9304 ! and is faster when NORD is very small (2-5), but worst case
9305 ! behavior can happen fairly probably (initially inverse sorted)
9306 ! In many cases, the refined quicksort method is faster.
9307 ! Michel Olagnon - Feb. 2000
9308 ! __________________________________________________________
9309 ! _________________________________________________________
9310 Real(kind = sp), Dimension (:), Intent (In) :: xdont
9311 Integer(kind = i4), Dimension (:), Intent (Out) :: IRNGT
9312 Integer(kind = i4), Intent (In) :: NORD
9313 ! __________________________________________________________
9314 Real(kind = sp) :: xwrk, xwrk1
9315 !
9316 Integer(kind = i4) :: ICRS, IDCR
9317 !
9318 irngt(1) = 1
9319 Do icrs = 2, nord
9320 xwrk = xdont(icrs)
9321 Do idcr = icrs - 1, 1, - 1
9322 If (xwrk >= xdont(irngt(idcr))) Exit
9323 irngt(idcr + 1) = irngt(idcr)
9324 End Do
9325 irngt(idcr + 1) = icrs
9326 End Do
9327 !
9328 xwrk1 = xdont(irngt(nord))
9329 Do icrs = nord + 1, SIZE (xdont)
9330 If (xdont(icrs) < xwrk1) Then
9331 xwrk = xdont(icrs)
9332 Do idcr = nord - 1, 1, - 1
9333 If (xwrk >= xdont(irngt(idcr))) Exit
9334 irngt(idcr + 1) = irngt(idcr)
9335 End Do
9336 irngt(idcr + 1) = icrs
9337 xwrk1 = xdont(irngt(nord))
9338 End If
9339 End Do
9340 !
9341 !
9342 End Subroutine r_rinpar
9343
9344 Subroutine i_rinpar (XDONT, IRNGT, NORD)
9345 ! Ranks partially XDONT by IRNGT, up to order NORD = size (IRNGT)
9346 ! __________________________________________________________
9347 ! This subroutine uses insertion sort, limiting insertion
9348 ! to the first NORD values. It does not use any work array
9349 ! and is faster when NORD is very small (2-5), but worst case
9350 ! behavior can happen fairly probably (initially inverse sorted)
9351 ! In many cases, the refined quicksort method is faster.
9352 ! Michel Olagnon - Feb. 2000
9353 ! __________________________________________________________
9354 ! __________________________________________________________
9355 Integer(kind = i4), Dimension (:), Intent (In) :: XDONT
9356 Integer(kind = i4), Dimension (:), Intent (Out) :: IRNGT
9357 Integer(kind = i4), Intent (In) :: NORD
9358 ! __________________________________________________________
9359 Integer(kind = i4) :: XWRK, XWRK1
9360 !
9361 Integer(kind = i4) :: ICRS, IDCR
9362 !
9363 irngt(1) = 1
9364 Do icrs = 2, nord
9365 xwrk = xdont(icrs)
9366 Do idcr = icrs - 1, 1, - 1
9367 If (xwrk >= xdont(irngt(idcr))) Exit
9368 irngt(idcr + 1) = irngt(idcr)
9369 End Do
9370 irngt(idcr + 1) = icrs
9371 End Do
9372 !
9373 xwrk1 = xdont(irngt(nord))
9374 Do icrs = nord + 1, SIZE (xdont)
9375 If (xdont(icrs) < xwrk1) Then
9376 xwrk = xdont(icrs)
9377 Do idcr = nord - 1, 1, - 1
9378 If (xwrk >= xdont(irngt(idcr))) Exit
9379 irngt(idcr + 1) = irngt(idcr)
9380 End Do
9381 irngt(idcr + 1) = icrs
9382 xwrk1 = xdont(irngt(nord))
9383 End If
9384 End Do
9385 !
9386 !
9387 End Subroutine i_rinpar
9388
9389 Subroutine d_rnkpar (XDONT, IRNGT, NORD)
9390 ! Ranks partially XDONT by IRNGT, up to order NORD
9391 ! __________________________________________________________
9392 ! This routine uses a pivoting strategy such as the one of
9393 ! finding the median based on the quicksort algorithm, but
9394 ! we skew the pivot choice to try to bring it to NORD as
9395 ! fast as possible. It uses 2 temporary arrays, where it
9396 ! stores the indices of the values smaller than the pivot
9397 ! (ILOWT), and the indices of values larger than the pivot
9398 ! that we might still need later on (IHIGT). It iterates
9399 ! until it can bring the number of values in ILOWT to
9400 ! exactly NORD, and then uses an insertion sort to rank
9401 ! this set, since it is supposedly small.
9402 ! Michel Olagnon - Feb. 2000
9403 ! __________________________________________________________
9404 ! __________________________________________________________
9405 real(kind = dp), Dimension (:), Intent (In) :: xdont
9406 Integer(kind = i4), Dimension (:), Intent (Out) :: IRNGT
9407 Integer(kind = i4), Intent (In) :: NORD
9408 ! __________________________________________________________
9409 real(kind = dp) :: xpiv, xpiv0, xwrk, xwrk1, xmin, xmax
9410 !
9411 Integer(kind = i4), Dimension (SIZE(XDONT)) :: ILOWT, IHIGT
9412 Integer(kind = i4) :: NDON, JHIG, JLOW, IHIG, IWRK, IWRK1, IWRK2, IWRK3
9413 Integer(kind = i4) :: IDEB, JDEB, IMIL, IFIN, NWRK, ICRS, IDCR, ILOW
9414 Integer(kind = i4) :: JLM2, JLM1, JHM2, JHM1
9415 !
9416 ndon = SIZE (xdont)
9417 !
9418 ! First loop is used to fill-in ILOWT, IHIGT at the same time
9419 !
9420 If (ndon < 2) Then
9421 If (nord >= 1) irngt(1) = 1
9422 Return
9423 End If
9424 !
9425 ! One chooses a pivot, best estimate possible to put fractile near
9426 ! mid-point of the set of low values.
9427 !
9428 If (xdont(2) < xdont(1)) Then
9429 ilowt(1) = 2
9430 ihigt(1) = 1
9431 Else
9432 ilowt(1) = 1
9433 ihigt(1) = 2
9434 End If
9435 !
9436 If (ndon < 3) Then
9437 If (nord >= 1) irngt(1) = ilowt(1)
9438 If (nord >= 2) irngt(2) = ihigt(1)
9439 Return
9440 End If
9441 !
9442 If (xdont(3) <= xdont(ihigt(1))) Then
9443 ihigt(2) = ihigt(1)
9444 If (xdont(3) < xdont(ilowt(1))) Then
9445 ihigt(1) = ilowt(1)
9446 ilowt(1) = 3
9447 Else
9448 ihigt(1) = 3
9449 End If
9450 Else
9451 ihigt(2) = 3
9452 End If
9453 !
9454 If (ndon < 4) Then
9455 If (nord >= 1) irngt(1) = ilowt(1)
9456 If (nord >= 2) irngt(2) = ihigt(1)
9457 If (nord >= 3) irngt(3) = ihigt(2)
9458 Return
9459 End If
9460 !
9461 If (xdont(ndon) <= xdont(ihigt(1))) Then
9462 ihigt(3) = ihigt(2)
9463 ihigt(2) = ihigt(1)
9464 If (xdont(ndon) < xdont(ilowt(1))) Then
9465 ihigt(1) = ilowt(1)
9466 ilowt(1) = ndon
9467 Else
9468 ihigt(1) = ndon
9469 End If
9470 Else
9471 if (xdont(ndon) < xdont(ihigt(2))) Then
9472 ihigt(3) = ihigt(2)
9473 ihigt(2) = ndon
9474 else
9475 ihigt(3) = ndon
9476 end if
9477 End If
9478 !
9479 If (ndon < 5) Then
9480 If (nord >= 1) irngt(1) = ilowt(1)
9481 If (nord >= 2) irngt(2) = ihigt(1)
9482 If (nord >= 3) irngt(3) = ihigt(2)
9483 If (nord >= 4) irngt(4) = ihigt(3)
9484 Return
9485 End If
9486 !
9487 jdeb = 0
9488 ideb = jdeb + 1
9489 jlow = ideb
9490 jhig = 3
9491 xpiv = xdont(ilowt(ideb)) + real(2 * nord, dp) / real(ndon + nord, dp) * &
9492 (xdont(ihigt(3)) - xdont(ilowt(ideb)))
9493 If (xpiv >= xdont(ihigt(1))) Then
9494 xpiv = xdont(ilowt(ideb)) + real(2 * nord, dp) / real(ndon + nord, dp) * &
9495 (xdont(ihigt(2)) - xdont(ilowt(ideb)))
9496 If (xpiv >= xdont(ihigt(1))) &
9497 xpiv = xdont(ilowt(ideb)) + real(2 * nord, dp) / real(ndon + nord, dp) * &
9498 (xdont(ihigt(1)) - xdont(ilowt(ideb)))
9499 End If
9500 xpiv0 = xpiv
9501 !
9502 ! One puts values > pivot in the end and those <= pivot
9503 ! at the beginning. This is split in 2 cases, so that
9504 ! we can skip the loop test a number of times.
9505 ! As we are also filling in the work arrays at the same time
9506 ! we stop filling in the IHIGT array as soon as we have more
9507 ! than enough values in ILOWT.
9508 !
9509 !
9510 If (xdont(ndon) > xpiv) Then
9511 icrs = 3
9512 Do
9513 icrs = icrs + 1
9514 If (xdont(icrs) > xpiv) Then
9515 If (icrs >= ndon) Exit
9516 jhig = jhig + 1
9517 ihigt(jhig) = icrs
9518 Else
9519 jlow = jlow + 1
9520 ilowt(jlow) = icrs
9521 If (jlow >= nord) Exit
9522 End If
9523 End Do
9524 !
9525 ! One restricts further processing because it is no use
9526 ! to store more high values
9527 !
9528 If (icrs < ndon - 1) Then
9529 Do
9530 icrs = icrs + 1
9531 If (xdont(icrs) <= xpiv) Then
9532 jlow = jlow + 1
9533 ilowt(jlow) = icrs
9534 Else If (icrs >= ndon) Then
9535 Exit
9536 End If
9537 End Do
9538 End If
9539 !
9540 !
9541 Else
9542 !
9543 ! Same as above, but this is not as easy to optimize, so the
9544 ! DO-loop is kept
9545 !
9546 Do icrs = 4, ndon - 1
9547 If (xdont(icrs) > xpiv) Then
9548 jhig = jhig + 1
9549 ihigt(jhig) = icrs
9550 Else
9551 jlow = jlow + 1
9552 ilowt(jlow) = icrs
9553 If (jlow >= nord) Exit
9554 End If
9555 End Do
9556 !
9557 If (icrs < ndon - 1) Then
9558 Do
9559 icrs = icrs + 1
9560 If (xdont(icrs) <= xpiv) Then
9561 If (icrs >= ndon) Exit
9562 jlow = jlow + 1
9563 ilowt(jlow) = icrs
9564 End If
9565 End Do
9566 End If
9567 End If
9568 !
9569 jlm2 = 0
9570 jlm1 = 0
9571 jhm2 = 0
9572 jhm1 = 0
9573 Do
9574 if (jlow == nord) Exit
9575 If (jlm2 == jlow .And. jhm2 == jhig) Then
9576 !
9577 ! We are oscillating. Perturbate by bringing JLOW closer by one
9578 ! to NORD
9579 !
9580 If (nord > jlow) Then
9581 xmin = xdont(ihigt(1))
9582 ihig = 1
9583 Do icrs = 2, jhig
9584 If (xdont(ihigt(icrs)) < xmin) Then
9585 xmin = xdont(ihigt(icrs))
9586 ihig = icrs
9587 End If
9588 End Do
9589 !
9590 jlow = jlow + 1
9591 ilowt(jlow) = ihigt(ihig)
9592 ihigt(ihig) = ihigt(jhig)
9593 jhig = jhig - 1
9594 Else
9595 ilow = ilowt(jlow)
9596 xmax = xdont(ilow)
9597 Do icrs = 1, jlow
9598 If (xdont(ilowt(icrs)) > xmax) Then
9599 iwrk = ilowt(icrs)
9600 xmax = xdont(iwrk)
9601 ilowt(icrs) = ilow
9602 ilow = iwrk
9603 End If
9604 End Do
9605 jlow = jlow - 1
9606 End If
9607 End If
9608 jlm2 = jlm1
9609 jlm1 = jlow
9610 jhm2 = jhm1
9611 jhm1 = jhig
9612 !
9613 ! We try to bring the number of values in the low values set
9614 ! closer to NORD.
9615 !
9616 Select Case (nord - jlow)
9617 Case (2 :)
9618 !
9619 ! Not enough values in low part, at least 2 are missing
9620 !
9621 Select Case (jhig)
9622 !!!!! CASE DEFAULT
9623 !!!!! write (*,*) "Assertion failed"
9624 !!!!! STOP
9625 !
9626 ! We make a special case when we have so few values in
9627 ! the high values set that it is bad performance to choose a pivot
9628 ! and apply the general algorithm.
9629 !
9630 Case (2)
9631 If (xdont(ihigt(1)) <= xdont(ihigt(2))) Then
9632 jlow = jlow + 1
9633 ilowt(jlow) = ihigt(1)
9634 jlow = jlow + 1
9635 ilowt(jlow) = ihigt(2)
9636 Else
9637 jlow = jlow + 1
9638 ilowt(jlow) = ihigt(2)
9639 jlow = jlow + 1
9640 ilowt(jlow) = ihigt(1)
9641 End If
9642 Exit
9643 !
9644 Case (3)
9645 !
9646 !
9647 iwrk1 = ihigt(1)
9648 iwrk2 = ihigt(2)
9649 iwrk3 = ihigt(3)
9650 If (xdont(iwrk2) < xdont(iwrk1)) Then
9651 ihigt(1) = iwrk2
9652 ihigt(2) = iwrk1
9653 iwrk2 = iwrk1
9654 End If
9655 If (xdont(iwrk2) > xdont(iwrk3)) Then
9656 ihigt(3) = iwrk2
9657 ihigt(2) = iwrk3
9658 iwrk2 = iwrk3
9659 If (xdont(iwrk2) < xdont(ihigt(1))) Then
9660 ihigt(2) = ihigt(1)
9661 ihigt(1) = iwrk2
9662 End If
9663 End If
9664 jhig = 0
9665 Do icrs = jlow + 1, nord
9666 jhig = jhig + 1
9667 ilowt(icrs) = ihigt(jhig)
9668 End Do
9669 jlow = nord
9670 Exit
9671 !
9672 Case (4 :)
9673 !
9674 !
9675 xpiv0 = xpiv
9676 ifin = jhig
9677 !
9678 ! One chooses a pivot from the 2 first values and the last one.
9679 ! This should ensure sufficient renewal between iterations to
9680 ! avoid worst case behavior effects.
9681 !
9682 iwrk1 = ihigt(1)
9683 iwrk2 = ihigt(2)
9684 iwrk3 = ihigt(ifin)
9685 If (xdont(iwrk2) < xdont(iwrk1)) Then
9686 ihigt(1) = iwrk2
9687 ihigt(2) = iwrk1
9688 iwrk2 = iwrk1
9689 End If
9690 If (xdont(iwrk2) > xdont(iwrk3)) Then
9691 ihigt(ifin) = iwrk2
9692 ihigt(2) = iwrk3
9693 iwrk2 = iwrk3
9694 If (xdont(iwrk2) < xdont(ihigt(1))) Then
9695 ihigt(2) = ihigt(1)
9696 ihigt(1) = iwrk2
9697 End If
9698 End If
9699 !
9700 jdeb = jlow
9701 nwrk = nord - jlow
9702 iwrk1 = ihigt(1)
9703 jlow = jlow + 1
9704 ilowt(jlow) = iwrk1
9705 xpiv = xdont(iwrk1) + real(nwrk, dp) / real(nord + nwrk, dp) * &
9706 (xdont(ihigt(ifin)) - xdont(iwrk1))
9707 !
9708 ! One takes values <= pivot to ILOWT
9709 ! Again, 2 parts, one where we take care of the remaining
9710 ! high values because we might still need them, and the
9711 ! other when we know that we will have more than enough
9712 ! low values in the end.
9713 !
9714 jhig = 0
9715 Do icrs = 2, ifin
9716 If (xdont(ihigt(icrs)) <= xpiv) Then
9717 jlow = jlow + 1
9718 ilowt(jlow) = ihigt(icrs)
9719 If (jlow >= nord) Exit
9720 Else
9721 jhig = jhig + 1
9722 ihigt(jhig) = ihigt(icrs)
9723 End If
9724 End Do
9725 !
9726 Do icrs = icrs + 1, ifin
9727 If (xdont(ihigt(icrs)) <= xpiv) Then
9728 jlow = jlow + 1
9729 ilowt(jlow) = ihigt(icrs)
9730 End If
9731 End Do
9732 End Select
9733 !
9734 !
9735 Case (1)
9736 !
9737 ! Only 1 value is missing in low part
9738 !
9739 xmin = xdont(ihigt(1))
9740 ihig = 1
9741 Do icrs = 2, jhig
9742 If (xdont(ihigt(icrs)) < xmin) Then
9743 xmin = xdont(ihigt(icrs))
9744 ihig = icrs
9745 End If
9746 End Do
9747 !
9748 jlow = jlow + 1
9749 ilowt(jlow) = ihigt(ihig)
9750 Exit
9751 !
9752 !
9753 Case (0)
9754 !
9755 ! Low part is exactly what we want
9756 !
9757 Exit
9758 !
9759 !
9760 Case (-5 : -1)
9761 !
9762 ! Only few values too many in low part
9763 !
9764 irngt(1) = ilowt(1)
9765 Do icrs = 2, nord
9766 iwrk = ilowt(icrs)
9767 xwrk = xdont(iwrk)
9768 Do idcr = icrs - 1, 1, - 1
9769 If (xwrk < xdont(irngt(idcr))) Then
9770 irngt(idcr + 1) = irngt(idcr)
9771 Else
9772 Exit
9773 End If
9774 End Do
9775 irngt(idcr + 1) = iwrk
9776 End Do
9777 !
9778 xwrk1 = xdont(irngt(nord))
9779 Do icrs = nord + 1, jlow
9780 If (xdont(ilowt(icrs)) < xwrk1) Then
9781 xwrk = xdont(ilowt(icrs))
9782 Do idcr = nord - 1, 1, - 1
9783 If (xwrk >= xdont(irngt(idcr))) Exit
9784 irngt(idcr + 1) = irngt(idcr)
9785 End Do
9786 irngt(idcr + 1) = ilowt(icrs)
9787 xwrk1 = xdont(irngt(nord))
9788 End If
9789 End Do
9790 !
9791 Return
9792 !
9793 !
9794 Case (: -6)
9795 !
9796 ! last case: too many values in low part
9797 !
9798 ideb = jdeb + 1
9799 imil = (jlow + ideb) / 2
9800 ifin = jlow
9801 !
9802 ! One chooses a pivot from 1st, last, and middle values
9803 !
9804 If (xdont(ilowt(imil)) < xdont(ilowt(ideb))) Then
9805 iwrk = ilowt(ideb)
9806 ilowt(ideb) = ilowt(imil)
9807 ilowt(imil) = iwrk
9808 End If
9809 If (xdont(ilowt(imil)) > xdont(ilowt(ifin))) Then
9810 iwrk = ilowt(ifin)
9811 ilowt(ifin) = ilowt(imil)
9812 ilowt(imil) = iwrk
9813 If (xdont(ilowt(imil)) < xdont(ilowt(ideb))) Then
9814 iwrk = ilowt(ideb)
9815 ilowt(ideb) = ilowt(imil)
9816 ilowt(imil) = iwrk
9817 End If
9818 End If
9819 If (ifin <= 3) Exit
9820 !
9821 xpiv = xdont(ilowt(1)) + real(nord, dp) / real(jlow + nord, dp) * &
9822 (xdont(ilowt(ifin)) - xdont(ilowt(1)))
9823 If (jdeb > 0) Then
9824 If (xpiv <= xpiv0) &
9825 xpiv = xpiv0 + real(2 * nord - jdeb, dp) / real(jlow + nord, dp) * &
9826 (xdont(ilowt(ifin)) - xpiv0)
9827 Else
9828 ideb = 1
9829 End If
9830 !
9831 ! One takes values > XPIV to IHIGT
9832 ! However, we do not process the first values if we have been
9833 ! through the case when we did not have enough low values
9834 !
9835 jhig = 0
9836 jlow = jdeb
9837 !
9838 If (xdont(ilowt(ifin)) > xpiv) Then
9839 icrs = jdeb
9840 Do
9841 icrs = icrs + 1
9842 If (xdont(ilowt(icrs)) > xpiv) Then
9843 jhig = jhig + 1
9844 ihigt(jhig) = ilowt(icrs)
9845 If (icrs >= ifin) Exit
9846 Else
9847 jlow = jlow + 1
9848 ilowt(jlow) = ilowt(icrs)
9849 If (jlow >= nord) Exit
9850 End If
9851 End Do
9852 !
9853 If (icrs < ifin) Then
9854 Do
9855 icrs = icrs + 1
9856 If (xdont(ilowt(icrs)) <= xpiv) Then
9857 jlow = jlow + 1
9858 ilowt(jlow) = ilowt(icrs)
9859 Else
9860 If (icrs >= ifin) Exit
9861 End If
9862 End Do
9863 End If
9864 Else
9865 Do icrs = ideb, ifin
9866 If (xdont(ilowt(icrs)) > xpiv) Then
9867 jhig = jhig + 1
9868 ihigt(jhig) = ilowt(icrs)
9869 Else
9870 jlow = jlow + 1
9871 ilowt(jlow) = ilowt(icrs)
9872 If (jlow >= nord) Exit
9873 End If
9874 End Do
9875 !
9876 Do icrs = icrs + 1, ifin
9877 If (xdont(ilowt(icrs)) <= xpiv) Then
9878 jlow = jlow + 1
9879 ilowt(jlow) = ilowt(icrs)
9880 End If
9881 End Do
9882 End If
9883 !
9884 End Select
9885 !
9886 End Do
9887 !
9888 ! Now, we only need to complete ranking of the 1:NORD set
9889 ! Assuming NORD is small, we use a simple insertion sort
9890 !
9891 irngt(1) = ilowt(1)
9892 Do icrs = 2, nord
9893 iwrk = ilowt(icrs)
9894 xwrk = xdont(iwrk)
9895 Do idcr = icrs - 1, 1, - 1
9896 If (xwrk < xdont(irngt(idcr))) Then
9897 irngt(idcr + 1) = irngt(idcr)
9898 Else
9899 Exit
9900 End If
9901 End Do
9902 irngt(idcr + 1) = iwrk
9903 End Do
9904 Return
9905 !
9906 !
9907 End Subroutine d_rnkpar
9908
9909 Subroutine r_rnkpar (XDONT, IRNGT, NORD)
9910 ! Ranks partially XDONT by IRNGT, up to order NORD
9911 ! __________________________________________________________
9912 ! This routine uses a pivoting strategy such as the one of
9913 ! finding the median based on the quicksort algorithm, but
9914 ! we skew the pivot choice to try to bring it to NORD as
9915 ! fast as possible. It uses 2 temporary arrays, where it
9916 ! stores the indices of the values smaller than the pivot
9917 ! (ILOWT), and the indices of values larger than the pivot
9918 ! that we might still need later on (IHIGT). It iterates
9919 ! until it can bring the number of values in ILOWT to
9920 ! exactly NORD, and then uses an insertion sort to rank
9921 ! this set, since it is supposedly small.
9922 ! Michel Olagnon - Feb. 2000
9923 ! __________________________________________________________
9924 ! _________________________________________________________
9925 Real(kind = sp), Dimension (:), Intent (In) :: xdont
9926 Integer(kind = i4), Dimension (:), Intent (Out) :: IRNGT
9927 Integer(kind = i4), Intent (In) :: NORD
9928 ! __________________________________________________________
9929 Real(kind = sp) :: xpiv, xpiv0, xwrk, xwrk1, xmin, xmax
9930 !
9931 Integer(kind = i4), Dimension (SIZE(XDONT)) :: ILOWT, IHIGT
9932 Integer(kind = i4) :: NDON, JHIG, JLOW, IHIG, IWRK, IWRK1, IWRK2, IWRK3
9933 Integer(kind = i4) :: IDEB, JDEB, IMIL, IFIN, NWRK, ICRS, IDCR, ILOW
9934 Integer(kind = i4) :: JLM2, JLM1, JHM2, JHM1
9935 !
9936 ndon = SIZE (xdont)
9937 !
9938 ! First loop is used to fill-in ILOWT, IHIGT at the same time
9939 !
9940 If (ndon < 2) Then
9941 If (nord >= 1) irngt(1) = 1
9942 Return
9943 End If
9944 !
9945 ! One chooses a pivot, best estimate possible to put fractile near
9946 ! mid-point of the set of low values.
9947 !
9948 If (xdont(2) < xdont(1)) Then
9949 ilowt(1) = 2
9950 ihigt(1) = 1
9951 Else
9952 ilowt(1) = 1
9953 ihigt(1) = 2
9954 End If
9955 !
9956 If (ndon < 3) Then
9957 If (nord >= 1) irngt(1) = ilowt(1)
9958 If (nord >= 2) irngt(2) = ihigt(1)
9959 Return
9960 End If
9961 !
9962 If (xdont(3) <= xdont(ihigt(1))) Then
9963 ihigt(2) = ihigt(1)
9964 If (xdont(3) < xdont(ilowt(1))) Then
9965 ihigt(1) = ilowt(1)
9966 ilowt(1) = 3
9967 Else
9968 ihigt(1) = 3
9969 End If
9970 Else
9971 ihigt(2) = 3
9972 End If
9973 !
9974 If (ndon < 4) Then
9975 If (nord >= 1) irngt(1) = ilowt(1)
9976 If (nord >= 2) irngt(2) = ihigt(1)
9977 If (nord >= 3) irngt(3) = ihigt(2)
9978 Return
9979 End If
9980 !
9981 If (xdont(ndon) <= xdont(ihigt(1))) Then
9982 ihigt(3) = ihigt(2)
9983 ihigt(2) = ihigt(1)
9984 If (xdont(ndon) < xdont(ilowt(1))) Then
9985 ihigt(1) = ilowt(1)
9986 ilowt(1) = ndon
9987 Else
9988 ihigt(1) = ndon
9989 End If
9990 Else
9991 if (xdont(ndon) < xdont(ihigt(2))) Then
9992 ihigt(3) = ihigt(2)
9993 ihigt(2) = ndon
9994 else
9995 ihigt(3) = ndon
9996 end if
9997 End If
9998 !
9999 If (ndon < 5) Then
10000 If (nord >= 1) irngt(1) = ilowt(1)
10001 If (nord >= 2) irngt(2) = ihigt(1)
10002 If (nord >= 3) irngt(3) = ihigt(2)
10003 If (nord >= 4) irngt(4) = ihigt(3)
10004 Return
10005 End If
10006 !
10007 jdeb = 0
10008 ideb = jdeb + 1
10009 jlow = ideb
10010 jhig = 3
10011 xpiv = xdont(ilowt(ideb)) + real(2 * nord, sp) / real(ndon + nord, sp) * &
10012 (xdont(ihigt(3)) - xdont(ilowt(ideb)))
10013 If (xpiv >= xdont(ihigt(1))) Then
10014 xpiv = xdont(ilowt(ideb)) + real(2 * nord, sp) / real(ndon + nord, sp) * &
10015 (xdont(ihigt(2)) - xdont(ilowt(ideb)))
10016 If (xpiv >= xdont(ihigt(1))) &
10017 xpiv = xdont(ilowt(ideb)) + real(2 * nord, sp) / real(ndon + nord, sp) * &
10018 (xdont(ihigt(1)) - xdont(ilowt(ideb)))
10019 End If
10020 xpiv0 = xpiv
10021 !
10022 ! One puts values > pivot in the end and those <= pivot
10023 ! at the beginning. This is split in 2 cases, so that
10024 ! we can skip the loop test a number of times.
10025 ! As we are also filling in the work arrays at the same time
10026 ! we stop filling in the IHIGT array as soon as we have more
10027 ! than enough values in ILOWT.
10028 !
10029 !
10030 If (xdont(ndon) > xpiv) Then
10031 icrs = 3
10032 Do
10033 icrs = icrs + 1
10034 If (xdont(icrs) > xpiv) Then
10035 If (icrs >= ndon) Exit
10036 jhig = jhig + 1
10037 ihigt(jhig) = icrs
10038 Else
10039 jlow = jlow + 1
10040 ilowt(jlow) = icrs
10041 If (jlow >= nord) Exit
10042 End If
10043 End Do
10044 !
10045 ! One restricts further processing because it is no use
10046 ! to store more high values
10047 !
10048 If (icrs < ndon - 1) Then
10049 Do
10050 icrs = icrs + 1
10051 If (xdont(icrs) <= xpiv) Then
10052 jlow = jlow + 1
10053 ilowt(jlow) = icrs
10054 Else If (icrs >= ndon) Then
10055 Exit
10056 End If
10057 End Do
10058 End If
10059 !
10060 !
10061 Else
10062 !
10063 ! Same as above, but this is not as easy to optimize, so the
10064 ! DO-loop is kept
10065 !
10066 Do icrs = 4, ndon - 1
10067 If (xdont(icrs) > xpiv) Then
10068 jhig = jhig + 1
10069 ihigt(jhig) = icrs
10070 Else
10071 jlow = jlow + 1
10072 ilowt(jlow) = icrs
10073 If (jlow >= nord) Exit
10074 End If
10075 End Do
10076 !
10077 If (icrs < ndon - 1) Then
10078 Do
10079 icrs = icrs + 1
10080 If (xdont(icrs) <= xpiv) Then
10081 If (icrs >= ndon) Exit
10082 jlow = jlow + 1
10083 ilowt(jlow) = icrs
10084 End If
10085 End Do
10086 End If
10087 End If
10088 !
10089 jlm2 = 0
10090 jlm1 = 0
10091 jhm2 = 0
10092 jhm1 = 0
10093 Do
10094 if (jlow == nord) Exit
10095 If (jlm2 == jlow .And. jhm2 == jhig) Then
10096 !
10097 ! We are oscillating. Perturbate by bringing JLOW closer by one
10098 ! to NORD
10099 !
10100 If (nord > jlow) Then
10101 xmin = xdont(ihigt(1))
10102 ihig = 1
10103 Do icrs = 2, jhig
10104 If (xdont(ihigt(icrs)) < xmin) Then
10105 xmin = xdont(ihigt(icrs))
10106 ihig = icrs
10107 End If
10108 End Do
10109 !
10110 jlow = jlow + 1
10111 ilowt(jlow) = ihigt(ihig)
10112 ihigt(ihig) = ihigt(jhig)
10113 jhig = jhig - 1
10114 Else
10115 ilow = ilowt(jlow)
10116 xmax = xdont(ilow)
10117 Do icrs = 1, jlow
10118 If (xdont(ilowt(icrs)) > xmax) Then
10119 iwrk = ilowt(icrs)
10120 xmax = xdont(iwrk)
10121 ilowt(icrs) = ilow
10122 ilow = iwrk
10123 End If
10124 End Do
10125 jlow = jlow - 1
10126 End If
10127 End If
10128 jlm2 = jlm1
10129 jlm1 = jlow
10130 jhm2 = jhm1
10131 jhm1 = jhig
10132 !
10133 ! We try to bring the number of values in the low values set
10134 ! closer to NORD.
10135 !
10136 Select Case (nord - jlow)
10137 Case (2 :)
10138 !
10139 ! Not enough values in low part, at least 2 are missing
10140 !
10141 Select Case (jhig)
10142 !!!!! CASE DEFAULT
10143 !!!!! write (*,*) "Assertion failed"
10144 !!!!! STOP
10145 !
10146 ! We make a special case when we have so few values in
10147 ! the high values set that it is bad performance to choose a pivot
10148 ! and apply the general algorithm.
10149 !
10150 Case (2)
10151 If (xdont(ihigt(1)) <= xdont(ihigt(2))) Then
10152 jlow = jlow + 1
10153 ilowt(jlow) = ihigt(1)
10154 jlow = jlow + 1
10155 ilowt(jlow) = ihigt(2)
10156 Else
10157 jlow = jlow + 1
10158 ilowt(jlow) = ihigt(2)
10159 jlow = jlow + 1
10160 ilowt(jlow) = ihigt(1)
10161 End If
10162 Exit
10163 !
10164 Case (3)
10165 !
10166 !
10167 iwrk1 = ihigt(1)
10168 iwrk2 = ihigt(2)
10169 iwrk3 = ihigt(3)
10170 If (xdont(iwrk2) < xdont(iwrk1)) Then
10171 ihigt(1) = iwrk2
10172 ihigt(2) = iwrk1
10173 iwrk2 = iwrk1
10174 End If
10175 If (xdont(iwrk2) > xdont(iwrk3)) Then
10176 ihigt(3) = iwrk2
10177 ihigt(2) = iwrk3
10178 iwrk2 = iwrk3
10179 If (xdont(iwrk2) < xdont(ihigt(1))) Then
10180 ihigt(2) = ihigt(1)
10181 ihigt(1) = iwrk2
10182 End If
10183 End If
10184 jhig = 0
10185 Do icrs = jlow + 1, nord
10186 jhig = jhig + 1
10187 ilowt(icrs) = ihigt(jhig)
10188 End Do
10189 jlow = nord
10190 Exit
10191 !
10192 Case (4 :)
10193 !
10194 !
10195 xpiv0 = xpiv
10196 ifin = jhig
10197 !
10198 ! One chooses a pivot from the 2 first values and the last one.
10199 ! This should ensure sufficient renewal between iterations to
10200 ! avoid worst case behavior effects.
10201 !
10202 iwrk1 = ihigt(1)
10203 iwrk2 = ihigt(2)
10204 iwrk3 = ihigt(ifin)
10205 If (xdont(iwrk2) < xdont(iwrk1)) Then
10206 ihigt(1) = iwrk2
10207 ihigt(2) = iwrk1
10208 iwrk2 = iwrk1
10209 End If
10210 If (xdont(iwrk2) > xdont(iwrk3)) Then
10211 ihigt(ifin) = iwrk2
10212 ihigt(2) = iwrk3
10213 iwrk2 = iwrk3
10214 If (xdont(iwrk2) < xdont(ihigt(1))) Then
10215 ihigt(2) = ihigt(1)
10216 ihigt(1) = iwrk2
10217 End If
10218 End If
10219 !
10220 jdeb = jlow
10221 nwrk = nord - jlow
10222 iwrk1 = ihigt(1)
10223 jlow = jlow + 1
10224 ilowt(jlow) = iwrk1
10225 xpiv = xdont(iwrk1) + real(nwrk, sp) / real(nord + nwrk, sp) * &
10226 (xdont(ihigt(ifin)) - xdont(iwrk1))
10227 !
10228 ! One takes values <= pivot to ILOWT
10229 ! Again, 2 parts, one where we take care of the remaining
10230 ! high values because we might still need them, and the
10231 ! other when we know that we will have more than enough
10232 ! low values in the end.
10233 !
10234 jhig = 0
10235 Do icrs = 2, ifin
10236 If (xdont(ihigt(icrs)) <= xpiv) Then
10237 jlow = jlow + 1
10238 ilowt(jlow) = ihigt(icrs)
10239 If (jlow >= nord) Exit
10240 Else
10241 jhig = jhig + 1
10242 ihigt(jhig) = ihigt(icrs)
10243 End If
10244 End Do
10245 !
10246 Do icrs = icrs + 1, ifin
10247 If (xdont(ihigt(icrs)) <= xpiv) Then
10248 jlow = jlow + 1
10249 ilowt(jlow) = ihigt(icrs)
10250 End If
10251 End Do
10252 End Select
10253 !
10254 !
10255 Case (1)
10256 !
10257 ! Only 1 value is missing in low part
10258 !
10259 xmin = xdont(ihigt(1))
10260 ihig = 1
10261 Do icrs = 2, jhig
10262 If (xdont(ihigt(icrs)) < xmin) Then
10263 xmin = xdont(ihigt(icrs))
10264 ihig = icrs
10265 End If
10266 End Do
10267 !
10268 jlow = jlow + 1
10269 ilowt(jlow) = ihigt(ihig)
10270 Exit
10271 !
10272 !
10273 Case (0)
10274 !
10275 ! Low part is exactly what we want
10276 !
10277 Exit
10278 !
10279 !
10280 Case (-5 : -1)
10281 !
10282 ! Only few values too many in low part
10283 !
10284 irngt(1) = ilowt(1)
10285 Do icrs = 2, nord
10286 iwrk = ilowt(icrs)
10287 xwrk = xdont(iwrk)
10288 Do idcr = icrs - 1, 1, - 1
10289 If (xwrk < xdont(irngt(idcr))) Then
10290 irngt(idcr + 1) = irngt(idcr)
10291 Else
10292 Exit
10293 End If
10294 End Do
10295 irngt(idcr + 1) = iwrk
10296 End Do
10297 !
10298 xwrk1 = xdont(irngt(nord))
10299 Do icrs = nord + 1, jlow
10300 If (xdont(ilowt(icrs)) < xwrk1) Then
10301 xwrk = xdont(ilowt(icrs))
10302 Do idcr = nord - 1, 1, - 1
10303 If (xwrk >= xdont(irngt(idcr))) Exit
10304 irngt(idcr + 1) = irngt(idcr)
10305 End Do
10306 irngt(idcr + 1) = ilowt(icrs)
10307 xwrk1 = xdont(irngt(nord))
10308 End If
10309 End Do
10310 !
10311 Return
10312 !
10313 !
10314 Case (: -6)
10315 !
10316 ! last case: too many values in low part
10317 !
10318 ideb = jdeb + 1
10319 imil = (jlow + ideb) / 2
10320 ifin = jlow
10321 !
10322 ! One chooses a pivot from 1st, last, and middle values
10323 !
10324 If (xdont(ilowt(imil)) < xdont(ilowt(ideb))) Then
10325 iwrk = ilowt(ideb)
10326 ilowt(ideb) = ilowt(imil)
10327 ilowt(imil) = iwrk
10328 End If
10329 If (xdont(ilowt(imil)) > xdont(ilowt(ifin))) Then
10330 iwrk = ilowt(ifin)
10331 ilowt(ifin) = ilowt(imil)
10332 ilowt(imil) = iwrk
10333 If (xdont(ilowt(imil)) < xdont(ilowt(ideb))) Then
10334 iwrk = ilowt(ideb)
10335 ilowt(ideb) = ilowt(imil)
10336 ilowt(imil) = iwrk
10337 End If
10338 End If
10339 If (ifin <= 3) Exit
10340 !
10341 xpiv = xdont(ilowt(1)) + real(nord, sp) / real(jlow + nord, sp) * &
10342 (xdont(ilowt(ifin)) - xdont(ilowt(1)))
10343 If (jdeb > 0) Then
10344 If (xpiv <= xpiv0) &
10345 xpiv = xpiv0 + real(2 * nord - jdeb, sp) / real(jlow + nord, sp) * &
10346 (xdont(ilowt(ifin)) - xpiv0)
10347 Else
10348 ideb = 1
10349 End If
10350 !
10351 ! One takes values > XPIV to IHIGT
10352 ! However, we do not process the first values if we have been
10353 ! through the case when we did not have enough low values
10354 !
10355 jhig = 0
10356 jlow = jdeb
10357 !
10358 If (xdont(ilowt(ifin)) > xpiv) Then
10359 icrs = jdeb
10360 Do
10361 icrs = icrs + 1
10362 If (xdont(ilowt(icrs)) > xpiv) Then
10363 jhig = jhig + 1
10364 ihigt(jhig) = ilowt(icrs)
10365 If (icrs >= ifin) Exit
10366 Else
10367 jlow = jlow + 1
10368 ilowt(jlow) = ilowt(icrs)
10369 If (jlow >= nord) Exit
10370 End If
10371 End Do
10372 !
10373 If (icrs < ifin) Then
10374 Do
10375 icrs = icrs + 1
10376 If (xdont(ilowt(icrs)) <= xpiv) Then
10377 jlow = jlow + 1
10378 ilowt(jlow) = ilowt(icrs)
10379 Else
10380 If (icrs >= ifin) Exit
10381 End If
10382 End Do
10383 End If
10384 Else
10385 Do icrs = ideb, ifin
10386 If (xdont(ilowt(icrs)) > xpiv) Then
10387 jhig = jhig + 1
10388 ihigt(jhig) = ilowt(icrs)
10389 Else
10390 jlow = jlow + 1
10391 ilowt(jlow) = ilowt(icrs)
10392 If (jlow >= nord) Exit
10393 End If
10394 End Do
10395 !
10396 Do icrs = icrs + 1, ifin
10397 If (xdont(ilowt(icrs)) <= xpiv) Then
10398 jlow = jlow + 1
10399 ilowt(jlow) = ilowt(icrs)
10400 End If
10401 End Do
10402 End If
10403 !
10404 End Select
10405 !
10406 End Do
10407 !
10408 ! Now, we only need to complete ranking of the 1:NORD set
10409 ! Assuming NORD is small, we use a simple insertion sort
10410 !
10411 irngt(1) = ilowt(1)
10412 Do icrs = 2, nord
10413 iwrk = ilowt(icrs)
10414 xwrk = xdont(iwrk)
10415 Do idcr = icrs - 1, 1, - 1
10416 If (xwrk < xdont(irngt(idcr))) Then
10417 irngt(idcr + 1) = irngt(idcr)
10418 Else
10419 Exit
10420 End If
10421 End Do
10422 irngt(idcr + 1) = iwrk
10423 End Do
10424 Return
10425 !
10426 !
10427 End Subroutine r_rnkpar
10428
10429 Subroutine i_rnkpar (XDONT, IRNGT, NORD)
10430 ! Ranks partially XDONT by IRNGT, up to order NORD
10431 ! __________________________________________________________
10432 ! This routine uses a pivoting strategy such as the one of
10433 ! finding the median based on the quicksort algorithm, but
10434 ! we skew the pivot choice to try to bring it to NORD as
10435 ! fast as possible. It uses 2 temporary arrays, where it
10436 ! stores the indices of the values smaller than the pivot
10437 ! (ILOWT), and the indices of values larger than the pivot
10438 ! that we might still need later on (IHIGT). It iterates
10439 ! until it can bring the number of values in ILOWT to
10440 ! exactly NORD, and then uses an insertion sort to rank
10441 ! this set, since it is supposedly small.
10442 ! Michel Olagnon - Feb. 2000
10443 ! __________________________________________________________
10444 ! __________________________________________________________
10445 Integer(kind = i4), Dimension (:), Intent (In) :: XDONT
10446 Integer(kind = i4), Dimension (:), Intent (Out) :: IRNGT
10447 Integer(kind = i4), Intent (In) :: NORD
10448 ! __________________________________________________________
10449 Integer(kind = i4) :: XPIV, XPIV0, XWRK, XWRK1, XMIN, XMAX
10450 !
10451 Integer(kind = i4), Dimension (SIZE(XDONT)) :: ILOWT, IHIGT
10452 Integer(kind = i4) :: NDON, JHIG, JLOW, IHIG, IWRK, IWRK1, IWRK2, IWRK3
10453 Integer(kind = i4) :: IDEB, JDEB, IMIL, IFIN, NWRK, ICRS, IDCR, ILOW
10454 Integer(kind = i4) :: JLM2, JLM1, JHM2, JHM1
10455 !
10456 ndon = SIZE (xdont)
10457 !
10458 ! First loop is used to fill-in ILOWT, IHIGT at the same time
10459 !
10460 If (ndon < 2) Then
10461 If (nord >= 1) irngt(1) = 1
10462 Return
10463 End If
10464 !
10465 ! One chooses a pivot, best estimate possible to put fractile near
10466 ! mid-point of the set of low values.
10467 !
10468 If (xdont(2) < xdont(1)) Then
10469 ilowt(1) = 2
10470 ihigt(1) = 1
10471 Else
10472 ilowt(1) = 1
10473 ihigt(1) = 2
10474 End If
10475 !
10476 If (ndon < 3) Then
10477 If (nord >= 1) irngt(1) = ilowt(1)
10478 If (nord >= 2) irngt(2) = ihigt(1)
10479 Return
10480 End If
10481 !
10482 If (xdont(3) <= xdont(ihigt(1))) Then
10483 ihigt(2) = ihigt(1)
10484 If (xdont(3) < xdont(ilowt(1))) Then
10485 ihigt(1) = ilowt(1)
10486 ilowt(1) = 3
10487 Else
10488 ihigt(1) = 3
10489 End If
10490 Else
10491 ihigt(2) = 3
10492 End If
10493 !
10494 If (ndon < 4) Then
10495 If (nord >= 1) irngt(1) = ilowt(1)
10496 If (nord >= 2) irngt(2) = ihigt(1)
10497 If (nord >= 3) irngt(3) = ihigt(2)
10498 Return
10499 End If
10500 !
10501 If (xdont(ndon) <= xdont(ihigt(1))) Then
10502 ihigt(3) = ihigt(2)
10503 ihigt(2) = ihigt(1)
10504 If (xdont(ndon) < xdont(ilowt(1))) Then
10505 ihigt(1) = ilowt(1)
10506 ilowt(1) = ndon
10507 Else
10508 ihigt(1) = ndon
10509 End If
10510 Else
10511 if (xdont(ndon) < xdont(ihigt(2))) Then
10512 ihigt(3) = ihigt(2)
10513 ihigt(2) = ndon
10514 else
10515 ihigt(3) = ndon
10516 end if
10517 End If
10518 !
10519 If (ndon < 5) Then
10520 If (nord >= 1) irngt(1) = ilowt(1)
10521 If (nord >= 2) irngt(2) = ihigt(1)
10522 If (nord >= 3) irngt(3) = ihigt(2)
10523 If (nord >= 4) irngt(4) = ihigt(3)
10524 Return
10525 End If
10526 !
10527 jdeb = 0
10528 ideb = jdeb + 1
10529 jlow = ideb
10530 jhig = 3
10531 xpiv = xdont(ilowt(ideb)) + int(real(2 * nord, sp) / real(ndon + nord, sp), i4) * &
10532 (xdont(ihigt(3)) - xdont(ilowt(ideb)))
10533 If (xpiv >= xdont(ihigt(1))) Then
10534 xpiv = xdont(ilowt(ideb)) + int(real(2 * nord, sp) / real(ndon + nord, sp), i4) * &
10535 (xdont(ihigt(2)) - xdont(ilowt(ideb)))
10536 If (xpiv >= xdont(ihigt(1))) &
10537 xpiv = xdont(ilowt(ideb)) + int(real(2 * nord, sp) / real(ndon + nord, sp), i4) * &
10538 (xdont(ihigt(1)) - xdont(ilowt(ideb)))
10539 End If
10540 xpiv0 = xpiv
10541 !
10542 ! One puts values > pivot in the end and those <= pivot
10543 ! at the beginning. This is split in 2 cases, so that
10544 ! we can skip the loop test a number of times.
10545 ! As we are also filling in the work arrays at the same time
10546 ! we stop filling in the IHIGT array as soon as we have more
10547 ! than enough values in ILOWT.
10548 !
10549 !
10550 If (xdont(ndon) > xpiv) Then
10551 icrs = 3
10552 Do
10553 icrs = icrs + 1
10554 If (xdont(icrs) > xpiv) Then
10555 If (icrs >= ndon) Exit
10556 jhig = jhig + 1
10557 ihigt(jhig) = icrs
10558 Else
10559 jlow = jlow + 1
10560 ilowt(jlow) = icrs
10561 If (jlow >= nord) Exit
10562 End If
10563 End Do
10564 !
10565 ! One restricts further processing because it is no use
10566 ! to store more high values
10567 !
10568 If (icrs < ndon - 1) Then
10569 Do
10570 icrs = icrs + 1
10571 If (xdont(icrs) <= xpiv) Then
10572 jlow = jlow + 1
10573 ilowt(jlow) = icrs
10574 Else If (icrs >= ndon) Then
10575 Exit
10576 End If
10577 End Do
10578 End If
10579 !
10580 !
10581 Else
10582 !
10583 ! Same as above, but this is not as easy to optimize, so the
10584 ! DO-loop is kept
10585 !
10586 Do icrs = 4, ndon - 1
10587 If (xdont(icrs) > xpiv) Then
10588 jhig = jhig + 1
10589 ihigt(jhig) = icrs
10590 Else
10591 jlow = jlow + 1
10592 ilowt(jlow) = icrs
10593 If (jlow >= nord) Exit
10594 End If
10595 End Do
10596 !
10597 If (icrs < ndon - 1) Then
10598 Do
10599 icrs = icrs + 1
10600 If (xdont(icrs) <= xpiv) Then
10601 If (icrs >= ndon) Exit
10602 jlow = jlow + 1
10603 ilowt(jlow) = icrs
10604 End If
10605 End Do
10606 End If
10607 End If
10608 !
10609 jlm2 = 0
10610 jlm1 = 0
10611 jhm2 = 0
10612 jhm1 = 0
10613 Do
10614 if (jlow == nord) Exit
10615 If (jlm2 == jlow .And. jhm2 == jhig) Then
10616 !
10617 ! We are oscillating. Perturbate by bringing JLOW closer by one
10618 ! to NORD
10619 !
10620 If (nord > jlow) Then
10621 xmin = xdont(ihigt(1))
10622 ihig = 1
10623 Do icrs = 2, jhig
10624 If (xdont(ihigt(icrs)) < xmin) Then
10625 xmin = xdont(ihigt(icrs))
10626 ihig = icrs
10627 End If
10628 End Do
10629 !
10630 jlow = jlow + 1
10631 ilowt(jlow) = ihigt(ihig)
10632 ihigt(ihig) = ihigt(jhig)
10633 jhig = jhig - 1
10634 Else
10635 ilow = ilowt(jlow)
10636 xmax = xdont(ilow)
10637 Do icrs = 1, jlow
10638 If (xdont(ilowt(icrs)) > xmax) Then
10639 iwrk = ilowt(icrs)
10640 xmax = xdont(iwrk)
10641 ilowt(icrs) = ilow
10642 ilow = iwrk
10643 End If
10644 End Do
10645 jlow = jlow - 1
10646 End If
10647 End If
10648 jlm2 = jlm1
10649 jlm1 = jlow
10650 jhm2 = jhm1
10651 jhm1 = jhig
10652 !
10653 ! We try to bring the number of values in the low values set
10654 ! closer to NORD.
10655 !
10656 Select Case (nord - jlow)
10657 Case (2 :)
10658 !
10659 ! Not enough values in low part, at least 2 are missing
10660 !
10661 Select Case (jhig)
10662 !!!!! CASE DEFAULT
10663 !!!!! write (*,*) "Assertion failed"
10664 !!!!! STOP
10665 !
10666 ! We make a special case when we have so few values in
10667 ! the high values set that it is bad performance to choose a pivot
10668 ! and apply the general algorithm.
10669 !
10670 Case (2)
10671 If (xdont(ihigt(1)) <= xdont(ihigt(2))) Then
10672 jlow = jlow + 1
10673 ilowt(jlow) = ihigt(1)
10674 jlow = jlow + 1
10675 ilowt(jlow) = ihigt(2)
10676 Else
10677 jlow = jlow + 1
10678 ilowt(jlow) = ihigt(2)
10679 jlow = jlow + 1
10680 ilowt(jlow) = ihigt(1)
10681 End If
10682 Exit
10683 !
10684 Case (3)
10685 !
10686 !
10687 iwrk1 = ihigt(1)
10688 iwrk2 = ihigt(2)
10689 iwrk3 = ihigt(3)
10690 If (xdont(iwrk2) < xdont(iwrk1)) Then
10691 ihigt(1) = iwrk2
10692 ihigt(2) = iwrk1
10693 iwrk2 = iwrk1
10694 End If
10695 If (xdont(iwrk2) > xdont(iwrk3)) Then
10696 ihigt(3) = iwrk2
10697 ihigt(2) = iwrk3
10698 iwrk2 = iwrk3
10699 If (xdont(iwrk2) < xdont(ihigt(1))) Then
10700 ihigt(2) = ihigt(1)
10701 ihigt(1) = iwrk2
10702 End If
10703 End If
10704 jhig = 0
10705 Do icrs = jlow + 1, nord
10706 jhig = jhig + 1
10707 ilowt(icrs) = ihigt(jhig)
10708 End Do
10709 jlow = nord
10710 Exit
10711 !
10712 Case (4 :)
10713 !
10714 !
10715 xpiv0 = xpiv
10716 ifin = jhig
10717 !
10718 ! One chooses a pivot from the 2 first values and the last one.
10719 ! This should ensure sufficient renewal between iterations to
10720 ! avoid worst case behavior effects.
10721 !
10722 iwrk1 = ihigt(1)
10723 iwrk2 = ihigt(2)
10724 iwrk3 = ihigt(ifin)
10725 If (xdont(iwrk2) < xdont(iwrk1)) Then
10726 ihigt(1) = iwrk2
10727 ihigt(2) = iwrk1
10728 iwrk2 = iwrk1
10729 End If
10730 If (xdont(iwrk2) > xdont(iwrk3)) Then
10731 ihigt(ifin) = iwrk2
10732 ihigt(2) = iwrk3
10733 iwrk2 = iwrk3
10734 If (xdont(iwrk2) < xdont(ihigt(1))) Then
10735 ihigt(2) = ihigt(1)
10736 ihigt(1) = iwrk2
10737 End If
10738 End If
10739 !
10740 jdeb = jlow
10741 nwrk = nord - jlow
10742 iwrk1 = ihigt(1)
10743 jlow = jlow + 1
10744 ilowt(jlow) = iwrk1
10745 xpiv = xdont(iwrk1) + int(real(nwrk, sp) / real(nord + nwrk, sp), i4) * &
10746 (xdont(ihigt(ifin)) - xdont(iwrk1))
10747 !
10748 ! One takes values <= pivot to ILOWT
10749 ! Again, 2 parts, one where we take care of the remaining
10750 ! high values because we might still need them, and the
10751 ! other when we know that we will have more than enough
10752 ! low values in the end.
10753 !
10754 jhig = 0
10755 Do icrs = 2, ifin
10756 If (xdont(ihigt(icrs)) <= xpiv) Then
10757 jlow = jlow + 1
10758 ilowt(jlow) = ihigt(icrs)
10759 If (jlow >= nord) Exit
10760 Else
10761 jhig = jhig + 1
10762 ihigt(jhig) = ihigt(icrs)
10763 End If
10764 End Do
10765 !
10766 Do icrs = icrs + 1, ifin
10767 If (xdont(ihigt(icrs)) <= xpiv) Then
10768 jlow = jlow + 1
10769 ilowt(jlow) = ihigt(icrs)
10770 End If
10771 End Do
10772 End Select
10773 !
10774 !
10775 Case (1)
10776 !
10777 ! Only 1 value is missing in low part
10778 !
10779 xmin = xdont(ihigt(1))
10780 ihig = 1
10781 Do icrs = 2, jhig
10782 If (xdont(ihigt(icrs)) < xmin) Then
10783 xmin = xdont(ihigt(icrs))
10784 ihig = icrs
10785 End If
10786 End Do
10787 !
10788 jlow = jlow + 1
10789 ilowt(jlow) = ihigt(ihig)
10790 Exit
10791 !
10792 !
10793 Case (0)
10794 !
10795 ! Low part is exactly what we want
10796 !
10797 Exit
10798 !
10799 !
10800 Case (-5 : -1)
10801 !
10802 ! Only few values too many in low part
10803 !
10804 irngt(1) = ilowt(1)
10805 Do icrs = 2, nord
10806 iwrk = ilowt(icrs)
10807 xwrk = xdont(iwrk)
10808 Do idcr = icrs - 1, 1, - 1
10809 If (xwrk < xdont(irngt(idcr))) Then
10810 irngt(idcr + 1) = irngt(idcr)
10811 Else
10812 Exit
10813 End If
10814 End Do
10815 irngt(idcr + 1) = iwrk
10816 End Do
10817 !
10818 xwrk1 = xdont(irngt(nord))
10819 Do icrs = nord + 1, jlow
10820 If (xdont(ilowt(icrs)) < xwrk1) Then
10821 xwrk = xdont(ilowt(icrs))
10822 Do idcr = nord - 1, 1, - 1
10823 If (xwrk >= xdont(irngt(idcr))) Exit
10824 irngt(idcr + 1) = irngt(idcr)
10825 End Do
10826 irngt(idcr + 1) = ilowt(icrs)
10827 xwrk1 = xdont(irngt(nord))
10828 End If
10829 End Do
10830 !
10831 Return
10832 !
10833 !
10834 Case (: -6)
10835 !
10836 ! last case: too many values in low part
10837 !
10838 ideb = jdeb + 1
10839 imil = (jlow + ideb) / 2
10840 ifin = jlow
10841 !
10842 ! One chooses a pivot from 1st, last, and middle values
10843 !
10844 If (xdont(ilowt(imil)) < xdont(ilowt(ideb))) Then
10845 iwrk = ilowt(ideb)
10846 ilowt(ideb) = ilowt(imil)
10847 ilowt(imil) = iwrk
10848 End If
10849 If (xdont(ilowt(imil)) > xdont(ilowt(ifin))) Then
10850 iwrk = ilowt(ifin)
10851 ilowt(ifin) = ilowt(imil)
10852 ilowt(imil) = iwrk
10853 If (xdont(ilowt(imil)) < xdont(ilowt(ideb))) Then
10854 iwrk = ilowt(ideb)
10855 ilowt(ideb) = ilowt(imil)
10856 ilowt(imil) = iwrk
10857 End If
10858 End If
10859 If (ifin <= 3) Exit
10860 !
10861 xpiv = xdont(ilowt(1)) + int(real(nord, sp) / real(jlow + nord, sp), i4) * &
10862 (xdont(ilowt(ifin)) - xdont(ilowt(1)))
10863 If (jdeb > 0) Then
10864 If (xpiv <= xpiv0) &
10865 xpiv = xpiv0 + int(real(2 * nord - jdeb, sp) / real(jlow + nord, sp), i4) * &
10866 (xdont(ilowt(ifin)) - xpiv0)
10867 Else
10868 ideb = 1
10869 End If
10870 !
10871 ! One takes values > XPIV to IHIGT
10872 ! However, we do not process the first values if we have been
10873 ! through the case when we did not have enough low values
10874 !
10875 jhig = 0
10876 jlow = jdeb
10877 !
10878 If (xdont(ilowt(ifin)) > xpiv) Then
10879 icrs = jdeb
10880 Do
10881 icrs = icrs + 1
10882 If (xdont(ilowt(icrs)) > xpiv) Then
10883 jhig = jhig + 1
10884 ihigt(jhig) = ilowt(icrs)
10885 If (icrs >= ifin) Exit
10886 Else
10887 jlow = jlow + 1
10888 ilowt(jlow) = ilowt(icrs)
10889 If (jlow >= nord) Exit
10890 End If
10891 End Do
10892 !
10893 If (icrs < ifin) Then
10894 Do
10895 icrs = icrs + 1
10896 If (xdont(ilowt(icrs)) <= xpiv) Then
10897 jlow = jlow + 1
10898 ilowt(jlow) = ilowt(icrs)
10899 Else
10900 If (icrs >= ifin) Exit
10901 End If
10902 End Do
10903 End If
10904 Else
10905 Do icrs = ideb, ifin
10906 If (xdont(ilowt(icrs)) > xpiv) Then
10907 jhig = jhig + 1
10908 ihigt(jhig) = ilowt(icrs)
10909 Else
10910 jlow = jlow + 1
10911 ilowt(jlow) = ilowt(icrs)
10912 If (jlow >= nord) Exit
10913 End If
10914 End Do
10915 !
10916 Do icrs = icrs + 1, ifin
10917 If (xdont(ilowt(icrs)) <= xpiv) Then
10918 jlow = jlow + 1
10919 ilowt(jlow) = ilowt(icrs)
10920 End If
10921 End Do
10922 End If
10923 !
10924 End Select
10925 !
10926 End Do
10927 !
10928 ! Now, we only need to complete ranking of the 1:NORD set
10929 ! Assuming NORD is small, we use a simple insertion sort
10930 !
10931 irngt(1) = ilowt(1)
10932 Do icrs = 2, nord
10933 iwrk = ilowt(icrs)
10934 xwrk = xdont(iwrk)
10935 Do idcr = icrs - 1, 1, - 1
10936 If (xwrk < xdont(irngt(idcr))) Then
10937 irngt(idcr + 1) = irngt(idcr)
10938 Else
10939 Exit
10940 End If
10941 End Do
10942 irngt(idcr + 1) = iwrk
10943 End Do
10944 Return
10945 !
10946 !
10947 End Subroutine i_rnkpar
10948
10949 Subroutine d_uniinv (XDONT, IGOEST)
10950 ! __________________________________________________________
10951 ! UNIINV = Merge-sort inverse ranking of an array, with removal of
10952 ! duplicate entries.
10953 ! The routine is similar to pure merge-sort ranking, but on
10954 ! the last pass, it sets indices in IGOEST to the rank
10955 ! of the value in the ordered set with duplicates removed.
10956 ! For performance reasons, the first 2 passes are taken
10957 ! out of the standard loop, and use dedicated coding.
10958 ! __________________________________________________________
10959 ! __________________________________________________________
10960 real(kind = dp), Dimension (:), Intent (In) :: xdont
10961 Integer(kind = i4), Dimension (:), Intent (Out) :: IGOEST
10962 ! __________________________________________________________
10963 real(kind = dp) :: xtst, xdona, xdonb
10964 !
10965 ! __________________________________________________________
10966 Integer(kind = i4), Dimension (SIZE(IGOEST)) :: JWRKT, IRNGT
10967 Integer(kind = i4) :: LMTNA, LMTNC, IRNG, IRNG1, IRNG2, NUNI
10968 Integer(kind = i4) :: NVAL, IIND, IWRKD, IWRK, IWRKF, JINDA, IINDA, IINDB
10969 !
10970 nval = min(SIZE(xdont), SIZE(igoest))
10971 !
10972 Select Case (nval)
10973 Case (: 0)
10974 Return
10975 Case (1)
10976 igoest(1) = 1
10977 Return
10978 Case Default
10979
10980 End Select
10981 !
10982 ! Fill-in the index array, creating ordered couples
10983 !
10984 Do iind = 2, nval, 2
10985 If (xdont(iind - 1) < xdont(iind)) Then
10986 irngt(iind - 1) = iind - 1
10987 irngt(iind) = iind
10988 Else
10989 irngt(iind - 1) = iind
10990 irngt(iind) = iind - 1
10991 End If
10992 End Do
10993 If (modulo(nval, 2) /= 0) Then
10994 irngt(nval) = nval
10995 End If
10996 !
10997 ! We will now have ordered subsets A - B - A - B - ...
10998 ! and merge A and B couples into C - C - ...
10999 !
11000 lmtna = 2
11001 lmtnc = 4
11002 !
11003 ! First iteration. The length of the ordered subsets goes from 2 to 4
11004 !
11005 Do
11006 If (nval <= 4) Exit
11007 !
11008 ! Loop on merges of A and B into C
11009 !
11010 Do iwrkd = 0, nval - 1, 4
11011 If ((iwrkd + 4) > nval) Then
11012 If ((iwrkd + 2) >= nval) Exit
11013 !
11014 ! 1 2 3
11015 !
11016 If (xdont(irngt(iwrkd + 2)) <= xdont(irngt(iwrkd + 3))) Exit
11017 !
11018 ! 1 3 2
11019 !
11020 If (xdont(irngt(iwrkd + 1)) <= xdont(irngt(iwrkd + 3))) Then
11021 irng2 = irngt(iwrkd + 2)
11022 irngt(iwrkd + 2) = irngt(iwrkd + 3)
11023 irngt(iwrkd + 3) = irng2
11024 !
11025 ! 3 1 2
11026 !
11027 Else
11028 irng1 = irngt(iwrkd + 1)
11029 irngt(iwrkd + 1) = irngt(iwrkd + 3)
11030 irngt(iwrkd + 3) = irngt(iwrkd + 2)
11031 irngt(iwrkd + 2) = irng1
11032 End If
11033 If (.true.) Exit ! Exit ! JM
11034 End If
11035 !
11036 ! 1 2 3 4
11037 !
11038 If (xdont(irngt(iwrkd + 2)) <= xdont(irngt(iwrkd + 3))) cycle
11039 !
11040 ! 1 3 x x
11041 !
11042 If (xdont(irngt(iwrkd + 1)) <= xdont(irngt(iwrkd + 3))) Then
11043 irng2 = irngt(iwrkd + 2)
11044 irngt(iwrkd + 2) = irngt(iwrkd + 3)
11045 If (xdont(irng2) <= xdont(irngt(iwrkd + 4))) Then
11046 ! 1 3 2 4
11047 irngt(iwrkd + 3) = irng2
11048 Else
11049 ! 1 3 4 2
11050 irngt(iwrkd + 3) = irngt(iwrkd + 4)
11051 irngt(iwrkd + 4) = irng2
11052 End If
11053 !
11054 ! 3 x x x
11055 !
11056 Else
11057 irng1 = irngt(iwrkd + 1)
11058 irng2 = irngt(iwrkd + 2)
11059 irngt(iwrkd + 1) = irngt(iwrkd + 3)
11060 If (xdont(irng1) <= xdont(irngt(iwrkd + 4))) Then
11061 irngt(iwrkd + 2) = irng1
11062 If (xdont(irng2) <= xdont(irngt(iwrkd + 4))) Then
11063 ! 3 1 2 4
11064 irngt(iwrkd + 3) = irng2
11065 Else
11066 ! 3 1 4 2
11067 irngt(iwrkd + 3) = irngt(iwrkd + 4)
11068 irngt(iwrkd + 4) = irng2
11069 End If
11070 Else
11071 ! 3 4 1 2
11072 irngt(iwrkd + 2) = irngt(iwrkd + 4)
11073 irngt(iwrkd + 3) = irng1
11074 irngt(iwrkd + 4) = irng2
11075 End If
11076 End If
11077 End Do
11078 !
11079 ! The Cs become As and Bs
11080 !
11081 lmtna = 4
11082 If (.true.) Exit ! Exit ! JM
11083 End Do
11084 !
11085 ! Iteration loop. Each time, the length of the ordered subsets
11086 ! is doubled.
11087 !
11088 Do
11089 If (2 * lmtna >= nval) Exit
11090 iwrkf = 0
11091 lmtnc = 2 * lmtnc
11092 !
11093 ! Loop on merges of A and B into C
11094 !
11095 Do
11096 iwrk = iwrkf
11097 iwrkd = iwrkf + 1
11098 jinda = iwrkf + lmtna
11099 iwrkf = iwrkf + lmtnc
11100 If (iwrkf >= nval) Then
11101 If (jinda >= nval) Exit
11102 iwrkf = nval
11103 End If
11104 iinda = 1
11105 iindb = jinda + 1
11106 !
11107 ! One steps in the C subset, that we create in the final rank array
11108 !
11109 ! Make a copy of the rank array for the iteration
11110 !
11111 jwrkt(1 : lmtna) = irngt(iwrkd : jinda)
11112 xdona = xdont(jwrkt(iinda))
11113 xdonb = xdont(irngt(iindb))
11114 !
11115 Do
11116 iwrk = iwrk + 1
11117 !
11118 ! We still have unprocessed values in both A and B
11119 !
11120 If (xdona > xdonb) Then
11121 irngt(iwrk) = irngt(iindb)
11122 iindb = iindb + 1
11123 If (iindb > iwrkf) Then
11124 ! Only A still with unprocessed values
11125 irngt(iwrk + 1 : iwrkf) = jwrkt(iinda : lmtna)
11126 Exit
11127 End If
11128 xdonb = xdont(irngt(iindb))
11129 Else
11130 irngt(iwrk) = jwrkt(iinda)
11131 iinda = iinda + 1
11132 If (iinda > lmtna) exit! Only B still with unprocessed values
11133 xdona = xdont(jwrkt(iinda))
11134 End If
11135 !
11136 End Do
11137 End Do
11138 !
11139 ! The Cs become As and Bs
11140 !
11141 lmtna = 2 * lmtna
11142 End Do
11143 !
11144 ! Last merge of A and B into C, with removal of duplicates.
11145 !
11146 iinda = 1
11147 iindb = lmtna + 1
11148 nuni = 0
11149 !
11150 ! One steps in the C subset, that we create in the final rank array
11151 !
11152 jwrkt(1 : lmtna) = irngt(1 : lmtna)
11153 If (iindb <= nval) Then
11154 xtst = nearless(min(xdont(jwrkt(1)), xdont(irngt(iindb))))
11155 Else
11156 xtst = nearless(xdont(jwrkt(1)))
11157 end if
11158 Do iwrk = 1, nval
11159 !
11160 ! We still have unprocessed values in both A and B
11161 !
11162 If (iinda <= lmtna) Then
11163 If (iindb <= nval) Then
11164 If (xdont(jwrkt(iinda)) > xdont(irngt(iindb))) Then
11165 irng = irngt(iindb)
11166 iindb = iindb + 1
11167 Else
11168 irng = jwrkt(iinda)
11169 iinda = iinda + 1
11170 End If
11171 Else
11172 !
11173 ! Only A still with unprocessed values
11174 !
11175 irng = jwrkt(iinda)
11176 iinda = iinda + 1
11177 End If
11178 Else
11179 !
11180 ! Only B still with unprocessed values
11181 !
11182 irng = irngt(iwrk)
11183 End If
11184 If (xdont(irng) > xtst) Then
11185 xtst = xdont(irng)
11186 nuni = nuni + 1
11187 End If
11188 igoest(irng) = nuni
11189 !
11190 End Do
11191 !
11192 Return
11193 !
11194 End Subroutine d_uniinv
11195
11196 Subroutine r_uniinv (XDONT, IGOEST)
11197 ! __________________________________________________________
11198 ! UNIINV = Merge-sort inverse ranking of an array, with removal of
11199 ! duplicate entries.
11200 ! The routine is similar to pure merge-sort ranking, but on
11201 ! the last pass, it sets indices in IGOEST to the rank
11202 ! of the value in the ordered set with duplicates removed.
11203 ! For performance reasons, the first 2 passes are taken
11204 ! out of the standard loop, and use dedicated coding.
11205 ! __________________________________________________________
11206 ! _________________________________________________________
11207 Real(kind = sp), Dimension (:), Intent (In) :: xdont
11208 Integer(kind = i4), Dimension (:), Intent (Out) :: IGOEST
11209 ! __________________________________________________________
11210 Real(kind = sp) :: xtst, xdona, xdonb
11211 !
11212 ! __________________________________________________________
11213 Integer(kind = i4), Dimension (SIZE(IGOEST)) :: JWRKT, IRNGT
11214 Integer(kind = i4) :: LMTNA, LMTNC, IRNG, IRNG1, IRNG2, NUNI
11215 Integer(kind = i4) :: NVAL, IIND, IWRKD, IWRK, IWRKF, JINDA, IINDA, IINDB
11216 !
11217 nval = min(SIZE(xdont), SIZE(igoest))
11218 !
11219 Select Case (nval)
11220 Case (: 0)
11221 Return
11222 Case (1)
11223 igoest(1) = 1
11224 Return
11225 Case Default
11226
11227 End Select
11228 !
11229 ! Fill-in the index array, creating ordered couples
11230 !
11231 Do iind = 2, nval, 2
11232 If (xdont(iind - 1) < xdont(iind)) Then
11233 irngt(iind - 1) = iind - 1
11234 irngt(iind) = iind
11235 Else
11236 irngt(iind - 1) = iind
11237 irngt(iind) = iind - 1
11238 End If
11239 End Do
11240 If (modulo(nval, 2) /= 0) Then
11241 irngt(nval) = nval
11242 End If
11243 !
11244 ! We will now have ordered subsets A - B - A - B - ...
11245 ! and merge A and B couples into C - C - ...
11246 !
11247 lmtna = 2
11248 lmtnc = 4
11249 !
11250 ! First iteration. The length of the ordered subsets goes from 2 to 4
11251 !
11252 Do
11253 If (nval <= 4) Exit
11254 !
11255 ! Loop on merges of A and B into C
11256 !
11257 Do iwrkd = 0, nval - 1, 4
11258 If ((iwrkd + 4) > nval) Then
11259 If ((iwrkd + 2) >= nval) Exit
11260 !
11261 ! 1 2 3
11262 !
11263 If (xdont(irngt(iwrkd + 2)) <= xdont(irngt(iwrkd + 3))) Exit
11264 !
11265 ! 1 3 2
11266 !
11267 If (xdont(irngt(iwrkd + 1)) <= xdont(irngt(iwrkd + 3))) Then
11268 irng2 = irngt(iwrkd + 2)
11269 irngt(iwrkd + 2) = irngt(iwrkd + 3)
11270 irngt(iwrkd + 3) = irng2
11271 !
11272 ! 3 1 2
11273 !
11274 Else
11275 irng1 = irngt(iwrkd + 1)
11276 irngt(iwrkd + 1) = irngt(iwrkd + 3)
11277 irngt(iwrkd + 3) = irngt(iwrkd + 2)
11278 irngt(iwrkd + 2) = irng1
11279 End If
11280 If (.true.) Exit ! Exit ! JM
11281 End If
11282 !
11283 ! 1 2 3 4
11284 !
11285 If (xdont(irngt(iwrkd + 2)) <= xdont(irngt(iwrkd + 3))) cycle
11286 !
11287 ! 1 3 x x
11288 !
11289 If (xdont(irngt(iwrkd + 1)) <= xdont(irngt(iwrkd + 3))) Then
11290 irng2 = irngt(iwrkd + 2)
11291 irngt(iwrkd + 2) = irngt(iwrkd + 3)
11292 If (xdont(irng2) <= xdont(irngt(iwrkd + 4))) Then
11293 ! 1 3 2 4
11294 irngt(iwrkd + 3) = irng2
11295 Else
11296 ! 1 3 4 2
11297 irngt(iwrkd + 3) = irngt(iwrkd + 4)
11298 irngt(iwrkd + 4) = irng2
11299 End If
11300 !
11301 ! 3 x x x
11302 !
11303 Else
11304 irng1 = irngt(iwrkd + 1)
11305 irng2 = irngt(iwrkd + 2)
11306 irngt(iwrkd + 1) = irngt(iwrkd + 3)
11307 If (xdont(irng1) <= xdont(irngt(iwrkd + 4))) Then
11308 irngt(iwrkd + 2) = irng1
11309 If (xdont(irng2) <= xdont(irngt(iwrkd + 4))) Then
11310 ! 3 1 2 4
11311 irngt(iwrkd + 3) = irng2
11312 Else
11313 ! 3 1 4 2
11314 irngt(iwrkd + 3) = irngt(iwrkd + 4)
11315 irngt(iwrkd + 4) = irng2
11316 End If
11317 Else
11318 ! 3 4 1 2
11319 irngt(iwrkd + 2) = irngt(iwrkd + 4)
11320 irngt(iwrkd + 3) = irng1
11321 irngt(iwrkd + 4) = irng2
11322 End If
11323 End If
11324 End Do
11325 !
11326 ! The Cs become As and Bs
11327 !
11328 lmtna = 4
11329 If (.true.) Exit ! Exit ! JM
11330 End Do
11331 !
11332 ! Iteration loop. Each time, the length of the ordered subsets
11333 ! is doubled.
11334 !
11335 Do
11336 If (2 * lmtna >= nval) Exit
11337 iwrkf = 0
11338 lmtnc = 2 * lmtnc
11339 !
11340 ! Loop on merges of A and B into C
11341 !
11342 Do
11343 iwrk = iwrkf
11344 iwrkd = iwrkf + 1
11345 jinda = iwrkf + lmtna
11346 iwrkf = iwrkf + lmtnc
11347 If (iwrkf >= nval) Then
11348 If (jinda >= nval) Exit
11349 iwrkf = nval
11350 End If
11351 iinda = 1
11352 iindb = jinda + 1
11353 !
11354 ! One steps in the C subset, that we create in the final rank array
11355 !
11356 ! Make a copy of the rank array for the iteration
11357 !
11358 jwrkt(1 : lmtna) = irngt(iwrkd : jinda)
11359 xdona = xdont(jwrkt(iinda))
11360 xdonb = xdont(irngt(iindb))
11361 !
11362 Do
11363 iwrk = iwrk + 1
11364 !
11365 ! We still have unprocessed values in both A and B
11366 !
11367 If (xdona > xdonb) Then
11368 irngt(iwrk) = irngt(iindb)
11369 iindb = iindb + 1
11370 If (iindb > iwrkf) Then
11371 ! Only A still with unprocessed values
11372 irngt(iwrk + 1 : iwrkf) = jwrkt(iinda : lmtna)
11373 Exit
11374 End If
11375 xdonb = xdont(irngt(iindb))
11376 Else
11377 irngt(iwrk) = jwrkt(iinda)
11378 iinda = iinda + 1
11379 If (iinda > lmtna) exit! Only B still with unprocessed values
11380 xdona = xdont(jwrkt(iinda))
11381 End If
11382 !
11383 End Do
11384 End Do
11385 !
11386 ! The Cs become As and Bs
11387 !
11388 lmtna = 2 * lmtna
11389 End Do
11390 !
11391 ! Last merge of A and B into C, with removal of duplicates.
11392 !
11393 iinda = 1
11394 iindb = lmtna + 1
11395 nuni = 0
11396 !
11397 ! One steps in the C subset, that we create in the final rank array
11398 !
11399 jwrkt(1 : lmtna) = irngt(1 : lmtna)
11400 If (iindb <= nval) Then
11401 xtst = nearless(min(xdont(jwrkt(1)), xdont(irngt(iindb))))
11402 Else
11403 xtst = nearless(xdont(jwrkt(1)))
11404 end if
11405 Do iwrk = 1, nval
11406 !
11407 ! We still have unprocessed values in both A and B
11408 !
11409 If (iinda <= lmtna) Then
11410 If (iindb <= nval) Then
11411 If (xdont(jwrkt(iinda)) > xdont(irngt(iindb))) Then
11412 irng = irngt(iindb)
11413 iindb = iindb + 1
11414 Else
11415 irng = jwrkt(iinda)
11416 iinda = iinda + 1
11417 End If
11418 Else
11419 !
11420 ! Only A still with unprocessed values
11421 !
11422 irng = jwrkt(iinda)
11423 iinda = iinda + 1
11424 End If
11425 Else
11426 !
11427 ! Only B still with unprocessed values
11428 !
11429 irng = irngt(iwrk)
11430 End If
11431 If (xdont(irng) > xtst) Then
11432 xtst = xdont(irng)
11433 nuni = nuni + 1
11434 End If
11435 igoest(irng) = nuni
11436 !
11437 End Do
11438 !
11439 Return
11440 !
11441 End Subroutine r_uniinv
11442
11443 Subroutine i_uniinv (XDONT, IGOEST)
11444 ! __________________________________________________________
11445 ! UNIINV = Merge-sort inverse ranking of an array, with removal of
11446 ! duplicate entries.
11447 ! The routine is similar to pure merge-sort ranking, but on
11448 ! the last pass, it sets indices in IGOEST to the rank
11449 ! of the value in the ordered set with duplicates removed.
11450 ! For performance reasons, the first 2 passes are taken
11451 ! out of the standard loop, and use dedicated coding.
11452 ! __________________________________________________________
11453 ! __________________________________________________________
11454 Integer(kind = i4), Dimension (:), Intent (In) :: XDONT
11455 Integer(kind = i4), Dimension (:), Intent (Out) :: IGOEST
11456 ! __________________________________________________________
11457 Integer(kind = i4) :: XTST, XDONA, XDONB
11458 !
11459 ! __________________________________________________________
11460 Integer(kind = i4), Dimension (SIZE(IGOEST)) :: JWRKT, IRNGT
11461 Integer(kind = i4) :: LMTNA, LMTNC, IRNG, IRNG1, IRNG2, NUNI
11462 Integer(kind = i4) :: NVAL, IIND, IWRKD, IWRK, IWRKF, JINDA, IINDA, IINDB
11463 !
11464 nval = min(SIZE(xdont), SIZE(igoest))
11465 !
11466 Select Case (nval)
11467 Case (: 0)
11468 Return
11469 Case (1)
11470 igoest(1) = 1
11471 Return
11472 Case Default
11473
11474 End Select
11475 !
11476 ! Fill-in the index array, creating ordered couples
11477 !
11478 Do iind = 2, nval, 2
11479 If (xdont(iind - 1) < xdont(iind)) Then
11480 irngt(iind - 1) = iind - 1
11481 irngt(iind) = iind
11482 Else
11483 irngt(iind - 1) = iind
11484 irngt(iind) = iind - 1
11485 End If
11486 End Do
11487 If (modulo(nval, 2) /= 0) Then
11488 irngt(nval) = nval
11489 End If
11490 !
11491 ! We will now have ordered subsets A - B - A - B - ...
11492 ! and merge A and B couples into C - C - ...
11493 !
11494 lmtna = 2
11495 lmtnc = 4
11496 !
11497 ! First iteration. The length of the ordered subsets goes from 2 to 4
11498 !
11499 Do
11500 If (nval <= 4) Exit
11501 !
11502 ! Loop on merges of A and B into C
11503 !
11504 Do iwrkd = 0, nval - 1, 4
11505 If ((iwrkd + 4) > nval) Then
11506 If ((iwrkd + 2) >= nval) Exit
11507 !
11508 ! 1 2 3
11509 !
11510 If (xdont(irngt(iwrkd + 2)) <= xdont(irngt(iwrkd + 3))) Exit
11511 !
11512 ! 1 3 2
11513 !
11514 If (xdont(irngt(iwrkd + 1)) <= xdont(irngt(iwrkd + 3))) Then
11515 irng2 = irngt(iwrkd + 2)
11516 irngt(iwrkd + 2) = irngt(iwrkd + 3)
11517 irngt(iwrkd + 3) = irng2
11518 !
11519 ! 3 1 2
11520 !
11521 Else
11522 irng1 = irngt(iwrkd + 1)
11523 irngt(iwrkd + 1) = irngt(iwrkd + 3)
11524 irngt(iwrkd + 3) = irngt(iwrkd + 2)
11525 irngt(iwrkd + 2) = irng1
11526 End If
11527 If (.true.) Exit ! Exit ! JM
11528 End If
11529 !
11530 ! 1 2 3 4
11531 !
11532 If (xdont(irngt(iwrkd + 2)) <= xdont(irngt(iwrkd + 3))) cycle
11533 !
11534 ! 1 3 x x
11535 !
11536 If (xdont(irngt(iwrkd + 1)) <= xdont(irngt(iwrkd + 3))) Then
11537 irng2 = irngt(iwrkd + 2)
11538 irngt(iwrkd + 2) = irngt(iwrkd + 3)
11539 If (xdont(irng2) <= xdont(irngt(iwrkd + 4))) Then
11540 ! 1 3 2 4
11541 irngt(iwrkd + 3) = irng2
11542 Else
11543 ! 1 3 4 2
11544 irngt(iwrkd + 3) = irngt(iwrkd + 4)
11545 irngt(iwrkd + 4) = irng2
11546 End If
11547 !
11548 ! 3 x x x
11549 !
11550 Else
11551 irng1 = irngt(iwrkd + 1)
11552 irng2 = irngt(iwrkd + 2)
11553 irngt(iwrkd + 1) = irngt(iwrkd + 3)
11554 If (xdont(irng1) <= xdont(irngt(iwrkd + 4))) Then
11555 irngt(iwrkd + 2) = irng1
11556 If (xdont(irng2) <= xdont(irngt(iwrkd + 4))) Then
11557 ! 3 1 2 4
11558 irngt(iwrkd + 3) = irng2
11559 Else
11560 ! 3 1 4 2
11561 irngt(iwrkd + 3) = irngt(iwrkd + 4)
11562 irngt(iwrkd + 4) = irng2
11563 End If
11564 Else
11565 ! 3 4 1 2
11566 irngt(iwrkd + 2) = irngt(iwrkd + 4)
11567 irngt(iwrkd + 3) = irng1
11568 irngt(iwrkd + 4) = irng2
11569 End If
11570 End If
11571 End Do
11572 !
11573 ! The Cs become As and Bs
11574 !
11575 lmtna = 4
11576 If (.true.) Exit ! Exit ! JM
11577 End Do
11578 !
11579 ! Iteration loop. Each time, the length of the ordered subsets
11580 ! is doubled.
11581 !
11582 Do
11583 If (2 * lmtna >= nval) Exit
11584 iwrkf = 0
11585 lmtnc = 2 * lmtnc
11586 !
11587 ! Loop on merges of A and B into C
11588 !
11589 Do
11590 iwrk = iwrkf
11591 iwrkd = iwrkf + 1
11592 jinda = iwrkf + lmtna
11593 iwrkf = iwrkf + lmtnc
11594 If (iwrkf >= nval) Then
11595 If (jinda >= nval) Exit
11596 iwrkf = nval
11597 End If
11598 iinda = 1
11599 iindb = jinda + 1
11600 !
11601 ! One steps in the C subset, that we create in the final rank array
11602 !
11603 ! Make a copy of the rank array for the iteration
11604 !
11605 jwrkt(1 : lmtna) = irngt(iwrkd : jinda)
11606 xdona = xdont(jwrkt(iinda))
11607 xdonb = xdont(irngt(iindb))
11608 !
11609 Do
11610 iwrk = iwrk + 1
11611 !
11612 ! We still have unprocessed values in both A and B
11613 !
11614 If (xdona > xdonb) Then
11615 irngt(iwrk) = irngt(iindb)
11616 iindb = iindb + 1
11617 If (iindb > iwrkf) Then
11618 ! Only A still with unprocessed values
11619 irngt(iwrk + 1 : iwrkf) = jwrkt(iinda : lmtna)
11620 Exit
11621 End If
11622 xdonb = xdont(irngt(iindb))
11623 Else
11624 irngt(iwrk) = jwrkt(iinda)
11625 iinda = iinda + 1
11626 If (iinda > lmtna) exit! Only B still with unprocessed values
11627 xdona = xdont(jwrkt(iinda))
11628 End If
11629 !
11630 End Do
11631 End Do
11632 !
11633 ! The Cs become As and Bs
11634 !
11635 lmtna = 2 * lmtna
11636 End Do
11637 !
11638 ! Last merge of A and B into C, with removal of duplicates.
11639 !
11640 iinda = 1
11641 iindb = lmtna + 1
11642 nuni = 0
11643 !
11644 ! One steps in the C subset, that we create in the final rank array
11645 !
11646 jwrkt(1 : lmtna) = irngt(1 : lmtna)
11647 If (iindb <= nval) Then
11648 xtst = nearless(min(xdont(jwrkt(1)), xdont(irngt(iindb))))
11649 Else
11650 xtst = nearless(xdont(jwrkt(1)))
11651 end if
11652 Do iwrk = 1, nval
11653 !
11654 ! We still have unprocessed values in both A and B
11655 !
11656 If (iinda <= lmtna) Then
11657 If (iindb <= nval) Then
11658 If (xdont(jwrkt(iinda)) > xdont(irngt(iindb))) Then
11659 irng = irngt(iindb)
11660 iindb = iindb + 1
11661 Else
11662 irng = jwrkt(iinda)
11663 iinda = iinda + 1
11664 End If
11665 Else
11666 !
11667 ! Only A still with unprocessed values
11668 !
11669 irng = jwrkt(iinda)
11670 iinda = iinda + 1
11671 End If
11672 Else
11673 !
11674 ! Only B still with unprocessed values
11675 !
11676 irng = irngt(iwrk)
11677 End If
11678 If (xdont(irng) > xtst) Then
11679 xtst = xdont(irng)
11680 nuni = nuni + 1
11681 End If
11682 igoest(irng) = nuni
11683 !
11684 End Do
11685 !
11686 Return
11687 !
11688 End Subroutine i_uniinv
11689
11690 Function d_nearless (XVAL) result (D_nl)
11691 ! Nearest value less than given value
11692 ! __________________________________________________________
11693 real(kind = dp), Intent (In) :: xval
11694 real(kind = dp) :: d_nl
11695 ! __________________________________________________________
11696 d_nl = nearest(xval, -1.0_dp)
11697 return
11698 !
11699 End Function d_nearless
11700
11701 Function r_nearless (XVAL) result (R_nl)
11702 ! Nearest value less than given value
11703 ! __________________________________________________________
11704 Real(kind = sp), Intent (In) :: xval
11705 Real(kind = sp) :: r_nl
11706 ! __________________________________________________________
11707 r_nl = nearest(xval, -1.0)
11708 return
11709 !
11710 End Function r_nearless
11711
11712 Function i_nearless (XVAL) result (I_nl)
11713 ! Nearest value less than given value
11714 ! __________________________________________________________
11715 Integer(kind = i4), Intent (In) :: XVAL
11716 Integer(kind = i4) :: I_nl
11717 ! __________________________________________________________
11718 i_nl = xval - 1
11719 return
11720 !
11721 End Function i_nearless
11722
11723
11724 Subroutine d_unipar (XDONT, IRNGT, NORD)
11725 ! Ranks partially XDONT by IRNGT, up to order NORD at most,
11726 ! removing duplicate entries
11727 ! __________________________________________________________
11728 ! This routine uses a pivoting strategy such as the one of
11729 ! finding the median based on the quicksort algorithm, but
11730 ! we skew the pivot choice to try to bring it to NORD as
11731 ! quickly as possible. It uses 2 temporary arrays, where it
11732 ! stores the indices of the values smaller than the pivot
11733 ! (ILOWT), and the indices of values larger than the pivot
11734 ! that we might still need later on (IHIGT). It iterates
11735 ! until it can bring the number of values in ILOWT to
11736 ! exactly NORD, and then uses an insertion sort to rank
11737 ! this set, since it is supposedly small. At all times, the
11738 ! NORD first values in ILOWT correspond to distinct values
11739 ! of the input array.
11740 ! Michel Olagnon - Feb. 2000
11741 ! __________________________________________________________
11742 ! __________________________________________________________
11743 real(kind = dp), Dimension (:), Intent (In) :: xdont
11744 Integer(kind = i4), Dimension (:), Intent (Out) :: IRNGT
11745 Integer(kind = i4), Intent (InOut) :: NORD
11746 ! __________________________________________________________
11747 real(kind = dp) :: xpiv, xwrk, xwrk1, xmin, xmax, xpiv0
11748 !
11749 Integer(kind = i4), Dimension (SIZE(XDONT)) :: ILOWT, IHIGT
11750 Integer(kind = i4) :: NDON, JHIG, JLOW, IHIG, IWRK, IWRK1, IWRK2, IWRK3
11751 Integer(kind = i4) :: IDEB, JDEB, IMIL, IFIN, NWRK, ICRS, IDCR, ILOW
11752 Integer(kind = i4) :: JLM2, JLM1, JHM2, JHM1
11753 !
11754 ndon = SIZE (xdont)
11755 !
11756 ! First loop is used to fill-in ILOWT, IHIGT at the same time
11757 !
11758 If (ndon < 2) Then
11759 If (nord >= 1) Then
11760 nord = 1
11761 irngt(1) = 1
11762 End If
11763 Return
11764 End If
11765 !
11766 ! One chooses a pivot, best estimate possible to put fractile near
11767 ! mid-point of the set of low values.
11768 !
11769 Do icrs = 2, ndon
11770 If (eq(xdont(icrs), xdont(1))) Then
11771 cycle
11772 Else If (xdont(icrs) < xdont(1)) Then
11773 ilowt(1) = icrs
11774 ihigt(1) = 1
11775 Else
11776 ilowt(1) = 1
11777 ihigt(1) = icrs
11778 End If
11779 If (.true.) Exit ! Exit ! JM
11780 End Do
11781 !
11782 If (ndon <= icrs) Then
11783 nord = min(nord, 2)
11784 If (nord >= 1) irngt(1) = ilowt(1)
11785 If (nord >= 2) irngt(2) = ihigt(1)
11786 Return
11787 End If
11788 !
11789 icrs = icrs + 1
11790 jhig = 1
11791 If (xdont(icrs) < xdont(ihigt(1))) Then
11792 If (xdont(icrs) < xdont(ilowt(1))) Then
11793 jhig = jhig + 1
11794 ihigt(jhig) = ihigt(1)
11795 ihigt(1) = ilowt(1)
11796 ilowt(1) = icrs
11797 Else If (xdont(icrs) > xdont(ilowt(1))) Then
11798 jhig = jhig + 1
11799 ihigt(jhig) = ihigt(1)
11800 ihigt(1) = icrs
11801 End If
11802 ElseIf (xdont(icrs) > xdont(ihigt(1))) Then
11803 jhig = jhig + 1
11804 ihigt(jhig) = icrs
11805 End If
11806 !
11807 If (ndon <= icrs) Then
11808 nord = min(nord, jhig + 1)
11809 If (nord >= 1) irngt(1) = ilowt(1)
11810 If (nord >= 2) irngt(2) = ihigt(1)
11811 If (nord >= 3) irngt(3) = ihigt(2)
11812 Return
11813 End If
11814 !
11815 If (xdont(ndon) < xdont(ihigt(1))) Then
11816 If (xdont(ndon) < xdont(ilowt(1))) Then
11817 Do idcr = jhig, 1, -1
11818 ihigt(idcr + 1) = ihigt(idcr)
11819 End Do
11820 ihigt(1) = ilowt(1)
11821 ilowt(1) = ndon
11822 jhig = jhig + 1
11823 ElseIf (xdont(ndon) > xdont(ilowt(1))) Then
11824 Do idcr = jhig, 1, -1
11825 ihigt(idcr + 1) = ihigt(idcr)
11826 End Do
11827 ihigt(1) = ndon
11828 jhig = jhig + 1
11829 End If
11830 ElseIf (xdont(ndon) > xdont(ihigt(1))) Then
11831 jhig = jhig + 1
11832 ihigt(jhig) = ndon
11833 End If
11834 !
11835 If (ndon <= icrs + 1) Then
11836 nord = min(nord, jhig + 1)
11837 If (nord >= 1) irngt(1) = ilowt(1)
11838 If (nord >= 2) irngt(2) = ihigt(1)
11839 If (nord >= 3) irngt(3) = ihigt(2)
11840 If (nord >= 4) irngt(4) = ihigt(3)
11841 Return
11842 End If
11843 !
11844 jdeb = 0
11845 ideb = jdeb + 1
11846 jlow = ideb
11847 xpiv = xdont(ilowt(ideb)) + real(2 * nord, dp) / real(ndon + nord, dp) * &
11848 (xdont(ihigt(3)) - xdont(ilowt(ideb)))
11849 If (xpiv >= xdont(ihigt(1))) Then
11850 xpiv = xdont(ilowt(ideb)) + real(2 * nord, dp) / real(ndon + nord, dp) * &
11851 (xdont(ihigt(2)) - xdont(ilowt(ideb)))
11852 If (xpiv >= xdont(ihigt(1))) &
11853 xpiv = xdont(ilowt(ideb)) + real(2 * nord, dp) / real(ndon + nord, dp) * &
11854 (xdont(ihigt(1)) - xdont(ilowt(ideb)))
11855 End If
11856 xpiv0 = xpiv
11857 !
11858 ! One puts values > pivot in the end and those <= pivot
11859 ! at the beginning. This is split in 2 cases, so that
11860 ! we can skip the loop test a number of times.
11861 ! As we are also filling in the work arrays at the same time
11862 ! we stop filling in the IHIGT array as soon as we have more
11863 ! than enough values in ILOWT, i.e. one more than
11864 ! strictly necessary so as to be able to come out of the
11865 ! case where JLOWT would be NORD distinct values followed
11866 ! by values that are exclusively duplicates of these.
11867 !
11868 !
11869 If (xdont(ndon) > xpiv) Then
11870 lowloop1 : Do
11871 icrs = icrs + 1
11872 If (xdont(icrs) > xpiv) Then
11873 If (icrs >= ndon) Exit
11874 jhig = jhig + 1
11875 ihigt(jhig) = icrs
11876 Else
11877 Do ilow = 1, jlow
11878 If (eq(xdont(icrs), xdont(ilowt(ilow)))) cycle lowloop1
11879 End Do
11880 jlow = jlow + 1
11881 ilowt(jlow) = icrs
11882 If (jlow >= nord) Exit
11883 End If
11884 End Do lowloop1
11885 !
11886 ! One restricts further processing because it is no use
11887 ! to store more high values
11888 !
11889 If (icrs < ndon - 1) Then
11890 Do
11891 icrs = icrs + 1
11892 If (xdont(icrs) <= xpiv) Then
11893 jlow = jlow + 1
11894 ilowt(jlow) = icrs
11895 Else If (icrs >= ndon) Then
11896 Exit
11897 End If
11898 End Do
11899 End If
11900 !
11901 !
11902 Else
11903 !
11904 ! Same as above, but this is not as easy to optimize, so the
11905 ! DO-loop is kept
11906 !
11907 lowloop2 : Do icrs = icrs + 1, ndon - 1
11908 If (xdont(icrs) > xpiv) Then
11909 jhig = jhig + 1
11910 ihigt(jhig) = icrs
11911 Else
11912 Do ilow = 1, jlow
11913 If (eq(xdont(icrs), xdont(ilowt(ilow)))) cycle lowloop2
11914 End Do
11915 jlow = jlow + 1
11916 ilowt(jlow) = icrs
11917 If (jlow >= nord) Exit
11918 End If
11919 End Do lowloop2
11920 !
11921 If (icrs < ndon - 1) Then
11922 Do
11923 icrs = icrs + 1
11924 If (xdont(icrs) <= xpiv) Then
11925 If (icrs >= ndon) Exit
11926 jlow = jlow + 1
11927 ilowt(jlow) = icrs
11928 End If
11929 End Do
11930 End If
11931 End If
11932 !
11933 jlm2 = 0
11934 jlm1 = 0
11935 jhm2 = 0
11936 jhm1 = 0
11937 Do
11938 if (jlow == nord) Exit
11939 If (jlm2 == jlow .And. jhm2 == jhig) Then
11940 !
11941 ! We are oscillating. Perturbate by bringing JLOW closer by one
11942 ! to NORD
11943 !
11944 If (nord > jlow) Then
11945 xmin = xdont(ihigt(1))
11946 ihig = 1
11947 Do icrs = 2, jhig
11948 If (xdont(ihigt(icrs)) < xmin) Then
11949 xmin = xdont(ihigt(icrs))
11950 ihig = icrs
11951 End If
11952 End Do
11953 !
11954 jlow = jlow + 1
11955 ilowt(jlow) = ihigt(ihig)
11956 ihig = 0
11957 Do icrs = 1, jhig
11958 If (ne(xdont(ihigt(icrs)), xmin)) then
11959 ihig = ihig + 1
11960 ihigt(ihig) = ihigt(icrs)
11961 End If
11962 End Do
11963 jhig = ihig
11964 Else
11965 ilow = ilowt(jlow)
11966 xmax = xdont(ilow)
11967 Do icrs = 1, jlow
11968 If (xdont(ilowt(icrs)) > xmax) Then
11969 iwrk = ilowt(icrs)
11970 xmax = xdont(iwrk)
11971 ilowt(icrs) = ilow
11972 ilow = iwrk
11973 End If
11974 End Do
11975 jlow = jlow - 1
11976 End If
11977 End If
11978 jlm2 = jlm1
11979 jlm1 = jlow
11980 jhm2 = jhm1
11981 jhm1 = jhig
11982 !
11983 ! We try to bring the number of values in the low values set
11984 ! closer to NORD. In order to make better pivot choices, we
11985 ! decrease NORD if we already know that we don't have that
11986 ! many distinct values as a whole.
11987 !
11988 IF (jlow + jhig < nord) nord = jlow + jhig
11989 Select Case (nord - jlow)
11990 ! ______________________________
11991 Case (2 :)
11992 !
11993 ! Not enough values in low part, at least 2 are missing
11994 !
11995 Select Case (jhig)
11996 !
11997 ! Not enough values in high part either (too many duplicates)
11998 !
11999 Case (0)
12000 nord = jlow
12001 !
12002 Case (1)
12003 jlow = jlow + 1
12004 ilowt(jlow) = ihigt(1)
12005 nord = jlow
12006 !
12007 ! We make a special case when we have so few values in
12008 ! the high values set that it is bad performance to choose a pivot
12009 ! and apply the general algorithm.
12010 !
12011 Case (2)
12012 If (le(xdont(ihigt(1)), xdont(ihigt(2)))) Then
12013 jlow = jlow + 1
12014 ilowt(jlow) = ihigt(1)
12015 jlow = jlow + 1
12016 ilowt(jlow) = ihigt(2)
12017 ElseIf (eq(xdont(ihigt(1)), xdont(ihigt(2)))) Then
12018 jlow = jlow + 1
12019 ilowt(jlow) = ihigt(1)
12020 nord = jlow
12021 Else
12022 jlow = jlow + 1
12023 ilowt(jlow) = ihigt(2)
12024 jlow = jlow + 1
12025 ilowt(jlow) = ihigt(1)
12026 End If
12027 Exit
12028 !
12029 Case (3)
12030 !
12031 !
12032 iwrk1 = ihigt(1)
12033 iwrk2 = ihigt(2)
12034 iwrk3 = ihigt(3)
12035 If (xdont(iwrk2) < xdont(iwrk1)) Then
12036 ihigt(1) = iwrk2
12037 ihigt(2) = iwrk1
12038 iwrk2 = iwrk1
12039 End If
12040 If (xdont(iwrk2) > xdont(iwrk3)) Then
12041 ihigt(3) = iwrk2
12042 ihigt(2) = iwrk3
12043 iwrk2 = iwrk3
12044 If (xdont(iwrk2) < xdont(ihigt(1))) Then
12045 ihigt(2) = ihigt(1)
12046 ihigt(1) = iwrk2
12047 End If
12048 End If
12049 jhig = 1
12050 jlow = jlow + 1
12051 ilowt(jlow) = ihigt(1)
12052 jhig = jhig + 1
12053 IF (ne(xdont(ihigt(jhig)), xdont(ilowt(jlow)))) Then
12054 jlow = jlow + 1
12055 ilowt(jlow) = ihigt(jhig)
12056 End If
12057 jhig = jhig + 1
12058 IF (ne(xdont(ihigt(jhig)), xdont(ilowt(jlow)))) Then
12059 jlow = jlow + 1
12060 ilowt(jlow) = ihigt(jhig)
12061 End If
12062 nord = min(jlow, nord)
12063 Exit
12064 !
12065 Case (4 :)
12066 !
12067 !
12068 xpiv0 = xpiv
12069 ifin = jhig
12070 !
12071 ! One chooses a pivot from the 2 first values and the last one.
12072 ! This should ensure sufficient renewal between iterations to
12073 ! avoid worst case behavior effects.
12074 !
12075 iwrk1 = ihigt(1)
12076 iwrk2 = ihigt(2)
12077 iwrk3 = ihigt(ifin)
12078 If (xdont(iwrk2) < xdont(iwrk1)) Then
12079 ihigt(1) = iwrk2
12080 ihigt(2) = iwrk1
12081 iwrk2 = iwrk1
12082 End If
12083 If (xdont(iwrk2) > xdont(iwrk3)) Then
12084 ihigt(ifin) = iwrk2
12085 ihigt(2) = iwrk3
12086 iwrk2 = iwrk3
12087 If (xdont(iwrk2) < xdont(ihigt(1))) Then
12088 ihigt(2) = ihigt(1)
12089 ihigt(1) = iwrk2
12090 End If
12091 End If
12092 !
12093 jdeb = jlow
12094 nwrk = nord - jlow
12095 iwrk1 = ihigt(1)
12096 xpiv = xdont(iwrk1) + real(nwrk, dp) / real(nord + nwrk, dp) * &
12097 (xdont(ihigt(ifin)) - xdont(iwrk1))
12098 !
12099 ! One takes values <= pivot to ILOWT
12100 ! Again, 2 parts, one where we take care of the remaining
12101 ! high values because we might still need them, and the
12102 ! other when we know that we will have more than enough
12103 ! low values in the end.
12104 !
12105 jhig = 0
12106 lowloop3 : Do icrs = 1, ifin
12107 If (xdont(ihigt(icrs)) <= xpiv) Then
12108 Do ilow = 1, jlow
12109 If (eq(xdont(ihigt(icrs)), xdont(ilowt(ilow)))) &
12110 cycle lowloop3
12111 End Do
12112 jlow = jlow + 1
12113 ilowt(jlow) = ihigt(icrs)
12114 If (jlow > nord) Exit
12115 Else
12116 jhig = jhig + 1
12117 ihigt(jhig) = ihigt(icrs)
12118 End If
12119 End Do lowloop3
12120 !
12121 Do icrs = icrs + 1, ifin
12122 If (xdont(ihigt(icrs)) <= xpiv) Then
12123 jlow = jlow + 1
12124 ilowt(jlow) = ihigt(icrs)
12125 End If
12126 End Do
12127 End Select
12128 !
12129 ! ______________________________
12130 !
12131 Case (1)
12132 !
12133 ! Only 1 value is missing in low part
12134 !
12135 xmin = xdont(ihigt(1))
12136 ihig = 1
12137 Do icrs = 2, jhig
12138 If (xdont(ihigt(icrs)) < xmin) Then
12139 xmin = xdont(ihigt(icrs))
12140 ihig = icrs
12141 End If
12142 End Do
12143 !
12144 jlow = jlow + 1
12145 ilowt(jlow) = ihigt(ihig)
12146 Exit
12147 !
12148 ! ______________________________
12149 !
12150 Case (0)
12151 !
12152 ! Low part is exactly what we want
12153 !
12154 Exit
12155 !
12156 ! ______________________________
12157 !
12158 Case (-5 : -1)
12159 !
12160 ! Only few values too many in low part
12161 !
12162 irngt(1) = ilowt(1)
12163 Do icrs = 2, nord
12164 iwrk = ilowt(icrs)
12165 xwrk = xdont(iwrk)
12166 Do idcr = icrs - 1, 1, - 1
12167 If (xwrk < xdont(irngt(idcr))) Then
12168 irngt(idcr + 1) = irngt(idcr)
12169 Else
12170 Exit
12171 End If
12172 End Do
12173 irngt(idcr + 1) = iwrk
12174 End Do
12175 !
12176 xwrk1 = xdont(irngt(nord))
12177 insert1 : Do icrs = nord + 1, jlow
12178 If (xdont(ilowt(icrs)) < xwrk1) Then
12179 xwrk = xdont(ilowt(icrs))
12180 Do ilow = 1, nord - 1
12181 If (xwrk <= xdont(irngt(ilow))) Then
12182 If (eq(xwrk, xdont(irngt(ilow)))) cycle insert1
12183 Exit
12184 End If
12185 End Do
12186 Do idcr = nord - 1, ilow, - 1
12187 irngt(idcr + 1) = irngt(idcr)
12188 End Do
12189 irngt(idcr + 1) = ilowt(icrs)
12190 xwrk1 = xdont(irngt(nord))
12191 End If
12192 End Do insert1
12193 !
12194 Return
12195 !
12196 ! ______________________________
12197 !
12198 Case (: -6)
12199 !
12200 ! last case: too many values in low part
12201 !
12202 ideb = jdeb + 1
12203 imil = min((jlow + ideb) / 2, nord)
12204 ifin = min(jlow, nord + 1)
12205 !
12206 ! One chooses a pivot from 1st, last, and middle values
12207 !
12208 If (xdont(ilowt(imil)) < xdont(ilowt(ideb))) Then
12209 iwrk = ilowt(ideb)
12210 ilowt(ideb) = ilowt(imil)
12211 ilowt(imil) = iwrk
12212 End If
12213 If (xdont(ilowt(imil)) > xdont(ilowt(ifin))) Then
12214 iwrk = ilowt(ifin)
12215 ilowt(ifin) = ilowt(imil)
12216 ilowt(imil) = iwrk
12217 If (xdont(ilowt(imil)) < xdont(ilowt(ideb))) Then
12218 iwrk = ilowt(ideb)
12219 ilowt(ideb) = ilowt(imil)
12220 ilowt(imil) = iwrk
12221 End If
12222 End If
12223 If (ifin <= 3) Exit
12224 !
12225 xpiv = xdont(ilowt(ideb)) + real(nord, dp) / real(jlow + nord, dp) * &
12226 (xdont(ilowt(ifin)) - xdont(ilowt(1)))
12227 If (jdeb > 0) Then
12228 If (xpiv <= xpiv0) &
12229 xpiv = xpiv0 + real(2 * nord - jdeb, dp) / real(jlow + nord, dp) * &
12230 (xdont(ilowt(ifin)) - xpiv0)
12231 Else
12232 ideb = 1
12233 End If
12234 !
12235 ! One takes values > XPIV to IHIGT
12236 ! However, we do not process the first values if we have been
12237 ! through the case when we did not have enough low values
12238 !
12239 jhig = 0
12240 ifin = jlow
12241 jlow = jdeb
12242 !
12243 If (xdont(ilowt(ifin)) > xpiv) Then
12244 icrs = jdeb
12245 lowloop4 : Do
12246 icrs = icrs + 1
12247 If (xdont(ilowt(icrs)) > xpiv) Then
12248 jhig = jhig + 1
12249 ihigt(jhig) = ilowt(icrs)
12250 If (icrs >= ifin) Exit
12251 Else
12252 xwrk1 = xdont(ilowt(icrs))
12253 Do ilow = ideb, jlow
12254 If (eq(xwrk1, xdont(ilowt(ilow)))) &
12255 cycle lowloop4
12256 End Do
12257 jlow = jlow + 1
12258 ilowt(jlow) = ilowt(icrs)
12259 If (jlow >= nord) Exit
12260 End If
12261 End Do lowloop4
12262 !
12263 If (icrs < ifin) Then
12264 Do
12265 icrs = icrs + 1
12266 If (xdont(ilowt(icrs)) <= xpiv) Then
12267 jlow = jlow + 1
12268 ilowt(jlow) = ilowt(icrs)
12269 Else
12270 If (icrs >= ifin) Exit
12271 End If
12272 End Do
12273 End If
12274 Else
12275 lowloop5 : Do icrs = ideb, ifin
12276 If (xdont(ilowt(icrs)) > xpiv) Then
12277 jhig = jhig + 1
12278 ihigt(jhig) = ilowt(icrs)
12279 Else
12280 xwrk1 = xdont(ilowt(icrs))
12281 Do ilow = ideb, jlow
12282 If (eq(xwrk1, xdont(ilowt(ilow)))) &
12283 cycle lowloop5
12284 End Do
12285 jlow = jlow + 1
12286 ilowt(jlow) = ilowt(icrs)
12287 If (jlow >= nord) Exit
12288 End If
12289 End Do lowloop5
12290 !
12291 Do icrs = icrs + 1, ifin
12292 If (xdont(ilowt(icrs)) <= xpiv) Then
12293 jlow = jlow + 1
12294 ilowt(jlow) = ilowt(icrs)
12295 End If
12296 End Do
12297 End If
12298 !
12299 End Select
12300 ! ______________________________
12301 !
12302 End Do
12303 !
12304 ! Now, we only need to complete ranking of the 1:NORD set
12305 ! Assuming NORD is small, we use a simple insertion sort
12306 !
12307 irngt(1) = ilowt(1)
12308 Do icrs = 2, nord
12309 iwrk = ilowt(icrs)
12310 xwrk = xdont(iwrk)
12311 Do idcr = icrs - 1, 1, - 1
12312 If (xwrk < xdont(irngt(idcr))) Then
12313 irngt(idcr + 1) = irngt(idcr)
12314 Else
12315 Exit
12316 End If
12317 End Do
12318 irngt(idcr + 1) = iwrk
12319 End Do
12320 Return
12321 !
12322 !
12323 End Subroutine d_unipar
12324
12325 Subroutine r_unipar (XDONT, IRNGT, NORD)
12326 ! Ranks partially XDONT by IRNGT, up to order NORD at most,
12327 ! removing duplicate entries
12328 ! __________________________________________________________
12329 ! This routine uses a pivoting strategy such as the one of
12330 ! finding the median based on the quicksort algorithm, but
12331 ! we skew the pivot choice to try to bring it to NORD as
12332 ! quickly as possible. It uses 2 temporary arrays, where it
12333 ! stores the indices of the values smaller than the pivot
12334 ! (ILOWT), and the indices of values larger than the pivot
12335 ! that we might still need later on (IHIGT). It iterates
12336 ! until it can bring the number of values in ILOWT to
12337 ! exactly NORD, and then uses an insertion sort to rank
12338 ! this set, since it is supposedly small. At all times, the
12339 ! NORD first values in ILOWT correspond to distinct values
12340 ! of the input array.
12341 ! Michel Olagnon - Feb. 2000
12342 ! __________________________________________________________
12343 ! _________________________________________________________
12344 Real(kind = sp), Dimension (:), Intent (In) :: xdont
12345 Integer(kind = i4), Dimension (:), Intent (Out) :: IRNGT
12346 Integer(kind = i4), Intent (InOut) :: NORD
12347 ! __________________________________________________________
12348 Real(kind = sp) :: xpiv, xwrk, xwrk1, xmin, xmax, xpiv0
12349 !
12350 Integer(kind = i4), Dimension (SIZE(XDONT)) :: ILOWT, IHIGT
12351 Integer(kind = i4) :: NDON, JHIG, JLOW, IHIG, IWRK, IWRK1, IWRK2, IWRK3
12352 Integer(kind = i4) :: IDEB, JDEB, IMIL, IFIN, NWRK, ICRS, IDCR, ILOW
12353 Integer(kind = i4) :: JLM2, JLM1, JHM2, JHM1
12354 !
12355 ndon = SIZE (xdont)
12356 !
12357 ! First loop is used to fill-in ILOWT, IHIGT at the same time
12358 !
12359 If (ndon < 2) Then
12360 If (nord >= 1) Then
12361 nord = 1
12362 irngt(1) = 1
12363 End If
12364 Return
12365 End If
12366 !
12367 ! One chooses a pivot, best estimate possible to put fractile near
12368 ! mid-point of the set of low values.
12369 !
12370 Do icrs = 2, ndon
12371 If (eq(xdont(icrs), xdont(1))) Then
12372 cycle
12373 Else If (xdont(icrs) < xdont(1)) Then
12374 ilowt(1) = icrs
12375 ihigt(1) = 1
12376 Else
12377 ilowt(1) = 1
12378 ihigt(1) = icrs
12379 End If
12380 If (.true.) Exit ! Exit ! JM
12381 End Do
12382 !
12383 If (ndon <= icrs) Then
12384 nord = min(nord, 2)
12385 If (nord >= 1) irngt(1) = ilowt(1)
12386 If (nord >= 2) irngt(2) = ihigt(1)
12387 Return
12388 End If
12389 !
12390 icrs = icrs + 1
12391 jhig = 1
12392 If (xdont(icrs) < xdont(ihigt(1))) Then
12393 If (xdont(icrs) < xdont(ilowt(1))) Then
12394 jhig = jhig + 1
12395 ihigt(jhig) = ihigt(1)
12396 ihigt(1) = ilowt(1)
12397 ilowt(1) = icrs
12398 Else If (xdont(icrs) > xdont(ilowt(1))) Then
12399 jhig = jhig + 1
12400 ihigt(jhig) = ihigt(1)
12401 ihigt(1) = icrs
12402 End If
12403 ElseIf (xdont(icrs) > xdont(ihigt(1))) Then
12404 jhig = jhig + 1
12405 ihigt(jhig) = icrs
12406 End If
12407 !
12408 If (ndon <= icrs) Then
12409 nord = min(nord, jhig + 1)
12410 If (nord >= 1) irngt(1) = ilowt(1)
12411 If (nord >= 2) irngt(2) = ihigt(1)
12412 If (nord >= 3) irngt(3) = ihigt(2)
12413 Return
12414 End If
12415 !
12416 If (xdont(ndon) < xdont(ihigt(1))) Then
12417 If (xdont(ndon) < xdont(ilowt(1))) Then
12418 Do idcr = jhig, 1, -1
12419 ihigt(idcr + 1) = ihigt(idcr)
12420 End Do
12421 ihigt(1) = ilowt(1)
12422 ilowt(1) = ndon
12423 jhig = jhig + 1
12424 ElseIf (xdont(ndon) > xdont(ilowt(1))) Then
12425 Do idcr = jhig, 1, -1
12426 ihigt(idcr + 1) = ihigt(idcr)
12427 End Do
12428 ihigt(1) = ndon
12429 jhig = jhig + 1
12430 End If
12431 ElseIf (xdont(ndon) > xdont(ihigt(1))) Then
12432 jhig = jhig + 1
12433 ihigt(jhig) = ndon
12434 End If
12435 !
12436 If (ndon <= icrs + 1) Then
12437 nord = min(nord, jhig + 1)
12438 If (nord >= 1) irngt(1) = ilowt(1)
12439 If (nord >= 2) irngt(2) = ihigt(1)
12440 If (nord >= 3) irngt(3) = ihigt(2)
12441 If (nord >= 4) irngt(4) = ihigt(3)
12442 Return
12443 End If
12444 !
12445 jdeb = 0
12446 ideb = jdeb + 1
12447 jlow = ideb
12448 xpiv = xdont(ilowt(ideb)) + real(2 * nord, sp) / real(ndon + nord, sp) * &
12449 (xdont(ihigt(3)) - xdont(ilowt(ideb)))
12450 If (xpiv >= xdont(ihigt(1))) Then
12451 xpiv = xdont(ilowt(ideb)) + real(2 * nord, sp) / real(ndon + nord, sp) * &
12452 (xdont(ihigt(2)) - xdont(ilowt(ideb)))
12453 If (xpiv >= xdont(ihigt(1))) &
12454 xpiv = xdont(ilowt(ideb)) + real(2 * nord, sp) / real(ndon + nord, sp) * &
12455 (xdont(ihigt(1)) - xdont(ilowt(ideb)))
12456 End If
12457 xpiv0 = xpiv
12458 !
12459 ! One puts values > pivot in the end and those <= pivot
12460 ! at the beginning. This is split in 2 cases, so that
12461 ! we can skip the loop test a number of times.
12462 ! As we are also filling in the work arrays at the same time
12463 ! we stop filling in the IHIGT array as soon as we have more
12464 ! than enough values in ILOWT, i.e. one more than
12465 ! strictly necessary so as to be able to come out of the
12466 ! case where JLOWT would be NORD distinct values followed
12467 ! by values that are exclusively duplicates of these.
12468 !
12469 !
12470 If (xdont(ndon) > xpiv) Then
12471 lowloop1 : Do
12472 icrs = icrs + 1
12473 If (xdont(icrs) > xpiv) Then
12474 If (icrs >= ndon) Exit
12475 jhig = jhig + 1
12476 ihigt(jhig) = icrs
12477 Else
12478 Do ilow = 1, jlow
12479 If (eq(xdont(icrs), xdont(ilowt(ilow)))) cycle lowloop1
12480 End Do
12481 jlow = jlow + 1
12482 ilowt(jlow) = icrs
12483 If (jlow >= nord) Exit
12484 End If
12485 End Do lowloop1
12486 !
12487 ! One restricts further processing because it is no use
12488 ! to store more high values
12489 !
12490 If (icrs < ndon - 1) Then
12491 Do
12492 icrs = icrs + 1
12493 If (xdont(icrs) <= xpiv) Then
12494 jlow = jlow + 1
12495 ilowt(jlow) = icrs
12496 Else If (icrs >= ndon) Then
12497 Exit
12498 End If
12499 End Do
12500 End If
12501 !
12502 !
12503 Else
12504 !
12505 ! Same as above, but this is not as easy to optimize, so the
12506 ! DO-loop is kept
12507 !
12508 lowloop2 : Do icrs = icrs + 1, ndon - 1
12509 If (xdont(icrs) > xpiv) Then
12510 jhig = jhig + 1
12511 ihigt(jhig) = icrs
12512 Else
12513 Do ilow = 1, jlow
12514 If (eq(xdont(icrs), xdont(ilowt(ilow)))) cycle lowloop2
12515 End Do
12516 jlow = jlow + 1
12517 ilowt(jlow) = icrs
12518 If (jlow >= nord) Exit
12519 End If
12520 End Do lowloop2
12521 !
12522 If (icrs < ndon - 1) Then
12523 Do
12524 icrs = icrs + 1
12525 If (xdont(icrs) <= xpiv) Then
12526 If (icrs >= ndon) Exit
12527 jlow = jlow + 1
12528 ilowt(jlow) = icrs
12529 End If
12530 End Do
12531 End If
12532 End If
12533 !
12534 jlm2 = 0
12535 jlm1 = 0
12536 jhm2 = 0
12537 jhm1 = 0
12538 Do
12539 if (jlow == nord) Exit
12540 If (jlm2 == jlow .And. jhm2 == jhig) Then
12541 !
12542 ! We are oscillating. Perturbate by bringing JLOW closer by one
12543 ! to NORD
12544 !
12545 If (nord > jlow) Then
12546 xmin = xdont(ihigt(1))
12547 ihig = 1
12548 Do icrs = 2, jhig
12549 If (xdont(ihigt(icrs)) < xmin) Then
12550 xmin = xdont(ihigt(icrs))
12551 ihig = icrs
12552 End If
12553 End Do
12554 !
12555 jlow = jlow + 1
12556 ilowt(jlow) = ihigt(ihig)
12557 ihig = 0
12558 Do icrs = 1, jhig
12559 If (ne(xdont(ihigt(icrs)), xmin)) then
12560 ihig = ihig + 1
12561 ihigt(ihig) = ihigt(icrs)
12562 End If
12563 End Do
12564 jhig = ihig
12565 Else
12566 ilow = ilowt(jlow)
12567 xmax = xdont(ilow)
12568 Do icrs = 1, jlow
12569 If (xdont(ilowt(icrs)) > xmax) Then
12570 iwrk = ilowt(icrs)
12571 xmax = xdont(iwrk)
12572 ilowt(icrs) = ilow
12573 ilow = iwrk
12574 End If
12575 End Do
12576 jlow = jlow - 1
12577 End If
12578 End If
12579 jlm2 = jlm1
12580 jlm1 = jlow
12581 jhm2 = jhm1
12582 jhm1 = jhig
12583 !
12584 ! We try to bring the number of values in the low values set
12585 ! closer to NORD. In order to make better pivot choices, we
12586 ! decrease NORD if we already know that we don't have that
12587 ! many distinct values as a whole.
12588 !
12589 IF (jlow + jhig < nord) nord = jlow + jhig
12590 Select Case (nord - jlow)
12591 ! ______________________________
12592 Case (2 :)
12593 !
12594 ! Not enough values in low part, at least 2 are missing
12595 !
12596 Select Case (jhig)
12597 !
12598 ! Not enough values in high part either (too many duplicates)
12599 !
12600 Case (0)
12601 nord = jlow
12602 !
12603 Case (1)
12604 jlow = jlow + 1
12605 ilowt(jlow) = ihigt(1)
12606 nord = jlow
12607 !
12608 ! We make a special case when we have so few values in
12609 ! the high values set that it is bad performance to choose a pivot
12610 ! and apply the general algorithm.
12611 !
12612 Case (2)
12613 If (le(xdont(ihigt(1)), xdont(ihigt(2)))) Then
12614 jlow = jlow + 1
12615 ilowt(jlow) = ihigt(1)
12616 jlow = jlow + 1
12617 ilowt(jlow) = ihigt(2)
12618 ElseIf (eq(xdont(ihigt(1)), xdont(ihigt(2)))) Then
12619 jlow = jlow + 1
12620 ilowt(jlow) = ihigt(1)
12621 nord = jlow
12622 Else
12623 jlow = jlow + 1
12624 ilowt(jlow) = ihigt(2)
12625 jlow = jlow + 1
12626 ilowt(jlow) = ihigt(1)
12627 End If
12628 Exit
12629 !
12630 Case (3)
12631 !
12632 !
12633 iwrk1 = ihigt(1)
12634 iwrk2 = ihigt(2)
12635 iwrk3 = ihigt(3)
12636 If (xdont(iwrk2) < xdont(iwrk1)) Then
12637 ihigt(1) = iwrk2
12638 ihigt(2) = iwrk1
12639 iwrk2 = iwrk1
12640 End If
12641 If (xdont(iwrk2) > xdont(iwrk3)) Then
12642 ihigt(3) = iwrk2
12643 ihigt(2) = iwrk3
12644 iwrk2 = iwrk3
12645 If (xdont(iwrk2) < xdont(ihigt(1))) Then
12646 ihigt(2) = ihigt(1)
12647 ihigt(1) = iwrk2
12648 End If
12649 End If
12650 jhig = 1
12651 jlow = jlow + 1
12652 ilowt(jlow) = ihigt(1)
12653 jhig = jhig + 1
12654 IF (ne(xdont(ihigt(jhig)), xdont(ilowt(jlow)))) Then
12655 jlow = jlow + 1
12656 ilowt(jlow) = ihigt(jhig)
12657 End If
12658 jhig = jhig + 1
12659 IF (ne(xdont(ihigt(jhig)), xdont(ilowt(jlow)))) Then
12660 jlow = jlow + 1
12661 ilowt(jlow) = ihigt(jhig)
12662 End If
12663 nord = min(jlow, nord)
12664 Exit
12665 !
12666 Case (4 :)
12667 !
12668 !
12669 xpiv0 = xpiv
12670 ifin = jhig
12671 !
12672 ! One chooses a pivot from the 2 first values and the last one.
12673 ! This should ensure sufficient renewal between iterations to
12674 ! avoid worst case behavior effects.
12675 !
12676 iwrk1 = ihigt(1)
12677 iwrk2 = ihigt(2)
12678 iwrk3 = ihigt(ifin)
12679 If (xdont(iwrk2) < xdont(iwrk1)) Then
12680 ihigt(1) = iwrk2
12681 ihigt(2) = iwrk1
12682 iwrk2 = iwrk1
12683 End If
12684 If (xdont(iwrk2) > xdont(iwrk3)) Then
12685 ihigt(ifin) = iwrk2
12686 ihigt(2) = iwrk3
12687 iwrk2 = iwrk3
12688 If (xdont(iwrk2) < xdont(ihigt(1))) Then
12689 ihigt(2) = ihigt(1)
12690 ihigt(1) = iwrk2
12691 End If
12692 End If
12693 !
12694 jdeb = jlow
12695 nwrk = nord - jlow
12696 iwrk1 = ihigt(1)
12697 xpiv = xdont(iwrk1) + real(nwrk, sp) / real(nord + nwrk, sp) * &
12698 (xdont(ihigt(ifin)) - xdont(iwrk1))
12699 !
12700 ! One takes values <= pivot to ILOWT
12701 ! Again, 2 parts, one where we take care of the remaining
12702 ! high values because we might still need them, and the
12703 ! other when we know that we will have more than enough
12704 ! low values in the end.
12705 !
12706 jhig = 0
12707 lowloop3 : Do icrs = 1, ifin
12708 If (xdont(ihigt(icrs)) <= xpiv) Then
12709 Do ilow = 1, jlow
12710 If (eq(xdont(ihigt(icrs)), xdont(ilowt(ilow)))) &
12711 cycle lowloop3
12712 End Do
12713 jlow = jlow + 1
12714 ilowt(jlow) = ihigt(icrs)
12715 If (jlow > nord) Exit
12716 Else
12717 jhig = jhig + 1
12718 ihigt(jhig) = ihigt(icrs)
12719 End If
12720 End Do lowloop3
12721 !
12722 Do icrs = icrs + 1, ifin
12723 If (xdont(ihigt(icrs)) <= xpiv) Then
12724 jlow = jlow + 1
12725 ilowt(jlow) = ihigt(icrs)
12726 End If
12727 End Do
12728 End Select
12729 !
12730 ! ______________________________
12731 !
12732 Case (1)
12733 !
12734 ! Only 1 value is missing in low part
12735 !
12736 xmin = xdont(ihigt(1))
12737 ihig = 1
12738 Do icrs = 2, jhig
12739 If (xdont(ihigt(icrs)) < xmin) Then
12740 xmin = xdont(ihigt(icrs))
12741 ihig = icrs
12742 End If
12743 End Do
12744 !
12745 jlow = jlow + 1
12746 ilowt(jlow) = ihigt(ihig)
12747 Exit
12748 !
12749 ! ______________________________
12750 !
12751 Case (0)
12752 !
12753 ! Low part is exactly what we want
12754 !
12755 Exit
12756 !
12757 ! ______________________________
12758 !
12759 Case (-5 : -1)
12760 !
12761 ! Only few values too many in low part
12762 !
12763 irngt(1) = ilowt(1)
12764 Do icrs = 2, nord
12765 iwrk = ilowt(icrs)
12766 xwrk = xdont(iwrk)
12767 Do idcr = icrs - 1, 1, - 1
12768 If (xwrk < xdont(irngt(idcr))) Then
12769 irngt(idcr + 1) = irngt(idcr)
12770 Else
12771 Exit
12772 End If
12773 End Do
12774 irngt(idcr + 1) = iwrk
12775 End Do
12776 !
12777 xwrk1 = xdont(irngt(nord))
12778 insert1 : Do icrs = nord + 1, jlow
12779 If (xdont(ilowt(icrs)) < xwrk1) Then
12780 xwrk = xdont(ilowt(icrs))
12781 Do ilow = 1, nord - 1
12782 If (xwrk <= xdont(irngt(ilow))) Then
12783 If (eq(xwrk, xdont(irngt(ilow)))) cycle insert1
12784 Exit
12785 End If
12786 End Do
12787 Do idcr = nord - 1, ilow, - 1
12788 irngt(idcr + 1) = irngt(idcr)
12789 End Do
12790 irngt(idcr + 1) = ilowt(icrs)
12791 xwrk1 = xdont(irngt(nord))
12792 End If
12793 End Do insert1
12794 !
12795 Return
12796 !
12797 ! ______________________________
12798 !
12799 Case (: -6)
12800 !
12801 ! last case: too many values in low part
12802 !
12803 ideb = jdeb + 1
12804 imil = min((jlow + ideb) / 2, nord)
12805 ifin = min(jlow, nord + 1)
12806 !
12807 ! One chooses a pivot from 1st, last, and middle values
12808 !
12809 If (xdont(ilowt(imil)) < xdont(ilowt(ideb))) Then
12810 iwrk = ilowt(ideb)
12811 ilowt(ideb) = ilowt(imil)
12812 ilowt(imil) = iwrk
12813 End If
12814 If (xdont(ilowt(imil)) > xdont(ilowt(ifin))) Then
12815 iwrk = ilowt(ifin)
12816 ilowt(ifin) = ilowt(imil)
12817 ilowt(imil) = iwrk
12818 If (xdont(ilowt(imil)) < xdont(ilowt(ideb))) Then
12819 iwrk = ilowt(ideb)
12820 ilowt(ideb) = ilowt(imil)
12821 ilowt(imil) = iwrk
12822 End If
12823 End If
12824 If (ifin <= 3) Exit
12825 !
12826 xpiv = xdont(ilowt(ideb)) + real(nord, sp) / real(jlow + nord, sp) * &
12827 (xdont(ilowt(ifin)) - xdont(ilowt(1)))
12828 If (jdeb > 0) Then
12829 If (xpiv <= xpiv0) &
12830 xpiv = xpiv0 + real(2 * nord - jdeb, sp) / real(jlow + nord, sp) * &
12831 (xdont(ilowt(ifin)) - xpiv0)
12832 Else
12833 ideb = 1
12834 End If
12835 !
12836 ! One takes values > XPIV to IHIGT
12837 ! However, we do not process the first values if we have been
12838 ! through the case when we did not have enough low values
12839 !
12840 jhig = 0
12841 ifin = jlow
12842 jlow = jdeb
12843 !
12844 If (xdont(ilowt(ifin)) > xpiv) Then
12845 icrs = jdeb
12846 lowloop4 : Do
12847 icrs = icrs + 1
12848 If (xdont(ilowt(icrs)) > xpiv) Then
12849 jhig = jhig + 1
12850 ihigt(jhig) = ilowt(icrs)
12851 If (icrs >= ifin) Exit
12852 Else
12853 xwrk1 = xdont(ilowt(icrs))
12854 Do ilow = ideb, jlow
12855 If (eq(xwrk1, xdont(ilowt(ilow)))) &
12856 cycle lowloop4
12857 End Do
12858 jlow = jlow + 1
12859 ilowt(jlow) = ilowt(icrs)
12860 If (jlow >= nord) Exit
12861 End If
12862 End Do lowloop4
12863 !
12864 If (icrs < ifin) Then
12865 Do
12866 icrs = icrs + 1
12867 If (xdont(ilowt(icrs)) <= xpiv) Then
12868 jlow = jlow + 1
12869 ilowt(jlow) = ilowt(icrs)
12870 Else
12871 If (icrs >= ifin) Exit
12872 End If
12873 End Do
12874 End If
12875 Else
12876 lowloop5 : Do icrs = ideb, ifin
12877 If (xdont(ilowt(icrs)) > xpiv) Then
12878 jhig = jhig + 1
12879 ihigt(jhig) = ilowt(icrs)
12880 Else
12881 xwrk1 = xdont(ilowt(icrs))
12882 Do ilow = ideb, jlow
12883 If (eq(xwrk1, xdont(ilowt(ilow)))) &
12884 cycle lowloop5
12885 End Do
12886 jlow = jlow + 1
12887 ilowt(jlow) = ilowt(icrs)
12888 If (jlow >= nord) Exit
12889 End If
12890 End Do lowloop5
12891 !
12892 Do icrs = icrs + 1, ifin
12893 If (xdont(ilowt(icrs)) <= xpiv) Then
12894 jlow = jlow + 1
12895 ilowt(jlow) = ilowt(icrs)
12896 End If
12897 End Do
12898 End If
12899 !
12900 End Select
12901 ! ______________________________
12902 !
12903 End Do
12904 !
12905 ! Now, we only need to complete ranking of the 1:NORD set
12906 ! Assuming NORD is small, we use a simple insertion sort
12907 !
12908 irngt(1) = ilowt(1)
12909 Do icrs = 2, nord
12910 iwrk = ilowt(icrs)
12911 xwrk = xdont(iwrk)
12912 Do idcr = icrs - 1, 1, - 1
12913 If (xwrk < xdont(irngt(idcr))) Then
12914 irngt(idcr + 1) = irngt(idcr)
12915 Else
12916 Exit
12917 End If
12918 End Do
12919 irngt(idcr + 1) = iwrk
12920 End Do
12921 Return
12922 !
12923 !
12924 End Subroutine r_unipar
12925
12926 Subroutine i_unipar (XDONT, IRNGT, NORD)
12927 ! Ranks partially XDONT by IRNGT, up to order NORD at most,
12928 ! removing duplicate entries
12929 ! __________________________________________________________
12930 ! This routine uses a pivoting strategy such as the one of
12931 ! finding the median based on the quicksort algorithm, but
12932 ! we skew the pivot choice to try to bring it to NORD as
12933 ! quickly as possible. It uses 2 temporary arrays, where it
12934 ! stores the indices of the values smaller than the pivot
12935 ! (ILOWT), and the indices of values larger than the pivot
12936 ! that we might still need later on (IHIGT). It iterates
12937 ! until it can bring the number of values in ILOWT to
12938 ! exactly NORD, and then uses an insertion sort to rank
12939 ! this set, since it is supposedly small. At all times, the
12940 ! NORD first values in ILOWT correspond to distinct values
12941 ! of the input array.
12942 ! Michel Olagnon - Feb. 2000
12943 ! __________________________________________________________
12944 ! __________________________________________________________
12945 Integer(kind = i4), Dimension (:), Intent (In) :: XDONT
12946 Integer(kind = i4), Dimension (:), Intent (Out) :: IRNGT
12947 Integer(kind = i4), Intent (InOut) :: NORD
12948 ! __________________________________________________________
12949 Integer(kind = i4) :: XPIV, XWRK, XWRK1, XMIN, XMAX, XPIV0
12950 !
12951 Integer(kind = i4), Dimension (SIZE(XDONT)) :: ILOWT, IHIGT
12952 Integer(kind = i4) :: NDON, JHIG, JLOW, IHIG, IWRK, IWRK1, IWRK2, IWRK3
12953 Integer(kind = i4) :: IDEB, JDEB, IMIL, IFIN, NWRK, ICRS, IDCR, ILOW
12954 Integer(kind = i4) :: JLM2, JLM1, JHM2, JHM1
12955 !
12956 ndon = SIZE (xdont)
12957 !
12958 ! First loop is used to fill-in ILOWT, IHIGT at the same time
12959 !
12960 If (ndon < 2) Then
12961 If (nord >= 1) Then
12962 nord = 1
12963 irngt(1) = 1
12964 End If
12965 Return
12966 End If
12967 !
12968 ! One chooses a pivot, best estimate possible to put fractile near
12969 ! mid-point of the set of low values.
12970 !
12971 Do icrs = 2, ndon
12972 If (xdont(icrs) == xdont(1)) Then
12973 cycle
12974 Else If (xdont(icrs) < xdont(1)) Then
12975 ilowt(1) = icrs
12976 ihigt(1) = 1
12977 Else
12978 ilowt(1) = 1
12979 ihigt(1) = icrs
12980 End If
12981 If (.true.) Exit ! Exit ! JM
12982 End Do
12983 !
12984 If (ndon <= icrs) Then
12985 nord = min(nord, 2)
12986 If (nord >= 1) irngt(1) = ilowt(1)
12987 If (nord >= 2) irngt(2) = ihigt(1)
12988 Return
12989 End If
12990 !
12991 icrs = icrs + 1
12992 jhig = 1
12993 If (xdont(icrs) < xdont(ihigt(1))) Then
12994 If (xdont(icrs) < xdont(ilowt(1))) Then
12995 jhig = jhig + 1
12996 ihigt(jhig) = ihigt(1)
12997 ihigt(1) = ilowt(1)
12998 ilowt(1) = icrs
12999 Else If (xdont(icrs) > xdont(ilowt(1))) Then
13000 jhig = jhig + 1
13001 ihigt(jhig) = ihigt(1)
13002 ihigt(1) = icrs
13003 End If
13004 ElseIf (xdont(icrs) > xdont(ihigt(1))) Then
13005 jhig = jhig + 1
13006 ihigt(jhig) = icrs
13007 End If
13008 !
13009 If (ndon <= icrs) Then
13010 nord = min(nord, jhig + 1)
13011 If (nord >= 1) irngt(1) = ilowt(1)
13012 If (nord >= 2) irngt(2) = ihigt(1)
13013 If (nord >= 3) irngt(3) = ihigt(2)
13014 Return
13015 End If
13016 !
13017 If (xdont(ndon) < xdont(ihigt(1))) Then
13018 If (xdont(ndon) < xdont(ilowt(1))) Then
13019 Do idcr = jhig, 1, -1
13020 ihigt(idcr + 1) = ihigt(idcr)
13021 End Do
13022 ihigt(1) = ilowt(1)
13023 ilowt(1) = ndon
13024 jhig = jhig + 1
13025 ElseIf (xdont(ndon) > xdont(ilowt(1))) Then
13026 Do idcr = jhig, 1, -1
13027 ihigt(idcr + 1) = ihigt(idcr)
13028 End Do
13029 ihigt(1) = ndon
13030 jhig = jhig + 1
13031 End If
13032 ElseIf (xdont(ndon) > xdont(ihigt(1))) Then
13033 jhig = jhig + 1
13034 ihigt(jhig) = ndon
13035 End If
13036 !
13037 If (ndon <= icrs + 1) Then
13038 nord = min(nord, jhig + 1)
13039 If (nord >= 1) irngt(1) = ilowt(1)
13040 If (nord >= 2) irngt(2) = ihigt(1)
13041 If (nord >= 3) irngt(3) = ihigt(2)
13042 If (nord >= 4) irngt(4) = ihigt(3)
13043 Return
13044 End If
13045 !
13046 jdeb = 0
13047 ideb = jdeb + 1
13048 jlow = ideb
13049 xpiv = xdont(ilowt(ideb)) + int(real(2 * nord, sp) / real(ndon + nord, sp), i4) * &
13050 (xdont(ihigt(3)) - xdont(ilowt(ideb)))
13051 If (xpiv >= xdont(ihigt(1))) Then
13052 xpiv = xdont(ilowt(ideb)) + int(real(2 * nord, sp) / real(ndon + nord, sp), i4) * &
13053 (xdont(ihigt(2)) - xdont(ilowt(ideb)))
13054 If (xpiv >= xdont(ihigt(1))) &
13055 xpiv = xdont(ilowt(ideb)) + int(real(2 * nord, sp) / real(ndon + nord, sp), i4) * &
13056 (xdont(ihigt(1)) - xdont(ilowt(ideb)))
13057 End If
13058 xpiv0 = xpiv
13059 !
13060 ! One puts values > pivot in the end and those <= pivot
13061 ! at the beginning. This is split in 2 cases, so that
13062 ! we can skip the loop test a number of times.
13063 ! As we are also filling in the work arrays at the same time
13064 ! we stop filling in the IHIGT array as soon as we have more
13065 ! than enough values in ILOWT, i.e. one more than
13066 ! strictly necessary so as to be able to come out of the
13067 ! case where JLOWT would be NORD distinct values followed
13068 ! by values that are exclusively duplicates of these.
13069 !
13070 !
13071 If (xdont(ndon) > xpiv) Then
13072 lowloop1 : Do
13073 icrs = icrs + 1
13074 If (xdont(icrs) > xpiv) Then
13075 If (icrs >= ndon) Exit
13076 jhig = jhig + 1
13077 ihigt(jhig) = icrs
13078 Else
13079 Do ilow = 1, jlow
13080 If (xdont(icrs) == xdont(ilowt(ilow))) cycle lowloop1
13081 End Do
13082 jlow = jlow + 1
13083 ilowt(jlow) = icrs
13084 If (jlow >= nord) Exit
13085 End If
13086 End Do lowloop1
13087 !
13088 ! One restricts further processing because it is no use
13089 ! to store more high values
13090 !
13091 If (icrs < ndon - 1) Then
13092 Do
13093 icrs = icrs + 1
13094 If (xdont(icrs) <= xpiv) Then
13095 jlow = jlow + 1
13096 ilowt(jlow) = icrs
13097 Else If (icrs >= ndon) Then
13098 Exit
13099 End If
13100 End Do
13101 End If
13102 !
13103 !
13104 Else
13105 !
13106 ! Same as above, but this is not as easy to optimize, so the
13107 ! DO-loop is kept
13108 !
13109 lowloop2 : Do icrs = icrs + 1, ndon - 1
13110 If (xdont(icrs) > xpiv) Then
13111 jhig = jhig + 1
13112 ihigt(jhig) = icrs
13113 Else
13114 Do ilow = 1, jlow
13115 If (xdont(icrs) == xdont(ilowt(ilow))) cycle lowloop2
13116 End Do
13117 jlow = jlow + 1
13118 ilowt(jlow) = icrs
13119 If (jlow >= nord) Exit
13120 End If
13121 End Do lowloop2
13122 !
13123 If (icrs < ndon - 1) Then
13124 Do
13125 icrs = icrs + 1
13126 If (xdont(icrs) <= xpiv) Then
13127 If (icrs >= ndon) Exit
13128 jlow = jlow + 1
13129 ilowt(jlow) = icrs
13130 End If
13131 End Do
13132 End If
13133 End If
13134 !
13135 jlm2 = 0
13136 jlm1 = 0
13137 jhm2 = 0
13138 jhm1 = 0
13139 Do
13140 if (jlow == nord) Exit
13141 If (jlm2 == jlow .And. jhm2 == jhig) Then
13142 !
13143 ! We are oscillating. Perturbate by bringing JLOW closer by one
13144 ! to NORD
13145 !
13146 If (nord > jlow) Then
13147 xmin = xdont(ihigt(1))
13148 ihig = 1
13149 Do icrs = 2, jhig
13150 If (xdont(ihigt(icrs)) < xmin) Then
13151 xmin = xdont(ihigt(icrs))
13152 ihig = icrs
13153 End If
13154 End Do
13155 !
13156 jlow = jlow + 1
13157 ilowt(jlow) = ihigt(ihig)
13158 ihig = 0
13159 Do icrs = 1, jhig
13160 If (xdont(ihigt(icrs)) /= xmin) then
13161 ihig = ihig + 1
13162 ihigt(ihig) = ihigt(icrs)
13163 End If
13164 End Do
13165 jhig = ihig
13166 Else
13167 ilow = ilowt(jlow)
13168 xmax = xdont(ilow)
13169 Do icrs = 1, jlow
13170 If (xdont(ilowt(icrs)) > xmax) Then
13171 iwrk = ilowt(icrs)
13172 xmax = xdont(iwrk)
13173 ilowt(icrs) = ilow
13174 ilow = iwrk
13175 End If
13176 End Do
13177 jlow = jlow - 1
13178 End If
13179 End If
13180 jlm2 = jlm1
13181 jlm1 = jlow
13182 jhm2 = jhm1
13183 jhm1 = jhig
13184 !
13185 ! We try to bring the number of values in the low values set
13186 ! closer to NORD. In order to make better pivot choices, we
13187 ! decrease NORD if we already know that we don't have that
13188 ! many distinct values as a whole.
13189 !
13190 IF (jlow + jhig < nord) nord = jlow + jhig
13191 Select Case (nord - jlow)
13192 ! ______________________________
13193 Case (2 :)
13194 !
13195 ! Not enough values in low part, at least 2 are missing
13196 !
13197 Select Case (jhig)
13198 !
13199 ! Not enough values in high part either (too many duplicates)
13200 !
13201 Case (0)
13202 nord = jlow
13203 !
13204 Case (1)
13205 jlow = jlow + 1
13206 ilowt(jlow) = ihigt(1)
13207 nord = jlow
13208 !
13209 ! We make a special case when we have so few values in
13210 ! the high values set that it is bad performance to choose a pivot
13211 ! and apply the general algorithm.
13212 !
13213 Case (2)
13214 If (xdont(ihigt(1)) <= xdont(ihigt(2))) Then
13215 jlow = jlow + 1
13216 ilowt(jlow) = ihigt(1)
13217 jlow = jlow + 1
13218 ilowt(jlow) = ihigt(2)
13219 ElseIf (xdont(ihigt(1)) == xdont(ihigt(2))) Then
13220 jlow = jlow + 1
13221 ilowt(jlow) = ihigt(1)
13222 nord = jlow
13223 Else
13224 jlow = jlow + 1
13225 ilowt(jlow) = ihigt(2)
13226 jlow = jlow + 1
13227 ilowt(jlow) = ihigt(1)
13228 End If
13229 Exit
13230 !
13231 Case (3)
13232 !
13233 !
13234 iwrk1 = ihigt(1)
13235 iwrk2 = ihigt(2)
13236 iwrk3 = ihigt(3)
13237 If (xdont(iwrk2) < xdont(iwrk1)) Then
13238 ihigt(1) = iwrk2
13239 ihigt(2) = iwrk1
13240 iwrk2 = iwrk1
13241 End If
13242 If (xdont(iwrk2) > xdont(iwrk3)) Then
13243 ihigt(3) = iwrk2
13244 ihigt(2) = iwrk3
13245 iwrk2 = iwrk3
13246 If (xdont(iwrk2) < xdont(ihigt(1))) Then
13247 ihigt(2) = ihigt(1)
13248 ihigt(1) = iwrk2
13249 End If
13250 End If
13251 jhig = 1
13252 jlow = jlow + 1
13253 ilowt(jlow) = ihigt(1)
13254 jhig = jhig + 1
13255 IF (xdont(ihigt(jhig)) /= xdont(ilowt(jlow))) Then
13256 jlow = jlow + 1
13257 ilowt(jlow) = ihigt(jhig)
13258 End If
13259 jhig = jhig + 1
13260 IF (xdont(ihigt(jhig)) /= xdont(ilowt(jlow))) Then
13261 jlow = jlow + 1
13262 ilowt(jlow) = ihigt(jhig)
13263 End If
13264 nord = min(jlow, nord)
13265 Exit
13266 !
13267 Case (4 :)
13268 !
13269 !
13270 xpiv0 = xpiv
13271 ifin = jhig
13272 !
13273 ! One chooses a pivot from the 2 first values and the last one.
13274 ! This should ensure sufficient renewal between iterations to
13275 ! avoid worst case behavior effects.
13276 !
13277 iwrk1 = ihigt(1)
13278 iwrk2 = ihigt(2)
13279 iwrk3 = ihigt(ifin)
13280 If (xdont(iwrk2) < xdont(iwrk1)) Then
13281 ihigt(1) = iwrk2
13282 ihigt(2) = iwrk1
13283 iwrk2 = iwrk1
13284 End If
13285 If (xdont(iwrk2) > xdont(iwrk3)) Then
13286 ihigt(ifin) = iwrk2
13287 ihigt(2) = iwrk3
13288 iwrk2 = iwrk3
13289 If (xdont(iwrk2) < xdont(ihigt(1))) Then
13290 ihigt(2) = ihigt(1)
13291 ihigt(1) = iwrk2
13292 End If
13293 End If
13294 !
13295 jdeb = jlow
13296 nwrk = nord - jlow
13297 iwrk1 = ihigt(1)
13298 xpiv = xdont(iwrk1) + int(real(nwrk, sp) / real(nord + nwrk, sp), i4) * &
13299 (xdont(ihigt(ifin)) - xdont(iwrk1))
13300 !
13301 ! One takes values <= pivot to ILOWT
13302 ! Again, 2 parts, one where we take care of the remaining
13303 ! high values because we might still need them, and the
13304 ! other when we know that we will have more than enough
13305 ! low values in the end.
13306 !
13307 jhig = 0
13308 lowloop3 : Do icrs = 1, ifin
13309 If (xdont(ihigt(icrs)) <= xpiv) Then
13310 Do ilow = 1, jlow
13311 If (xdont(ihigt(icrs)) == xdont(ilowt(ilow))) &
13312 cycle lowloop3
13313 End Do
13314 jlow = jlow + 1
13315 ilowt(jlow) = ihigt(icrs)
13316 If (jlow > nord) Exit
13317 Else
13318 jhig = jhig + 1
13319 ihigt(jhig) = ihigt(icrs)
13320 End If
13321 End Do lowloop3
13322 !
13323 Do icrs = icrs + 1, ifin
13324 If (xdont(ihigt(icrs)) <= xpiv) Then
13325 jlow = jlow + 1
13326 ilowt(jlow) = ihigt(icrs)
13327 End If
13328 End Do
13329 End Select
13330 !
13331 ! ______________________________
13332 !
13333 Case (1)
13334 !
13335 ! Only 1 value is missing in low part
13336 !
13337 xmin = xdont(ihigt(1))
13338 ihig = 1
13339 Do icrs = 2, jhig
13340 If (xdont(ihigt(icrs)) < xmin) Then
13341 xmin = xdont(ihigt(icrs))
13342 ihig = icrs
13343 End If
13344 End Do
13345 !
13346 jlow = jlow + 1
13347 ilowt(jlow) = ihigt(ihig)
13348 Exit
13349 !
13350 ! ______________________________
13351 !
13352 Case (0)
13353 !
13354 ! Low part is exactly what we want
13355 !
13356 Exit
13357 !
13358 ! ______________________________
13359 !
13360 Case (-5 : -1)
13361 !
13362 ! Only few values too many in low part
13363 !
13364 irngt(1) = ilowt(1)
13365 Do icrs = 2, nord
13366 iwrk = ilowt(icrs)
13367 xwrk = xdont(iwrk)
13368 Do idcr = icrs - 1, 1, - 1
13369 If (xwrk < xdont(irngt(idcr))) Then
13370 irngt(idcr + 1) = irngt(idcr)
13371 Else
13372 Exit
13373 End If
13374 End Do
13375 irngt(idcr + 1) = iwrk
13376 End Do
13377 !
13378 xwrk1 = xdont(irngt(nord))
13379 insert1 : Do icrs = nord + 1, jlow
13380 If (xdont(ilowt(icrs)) < xwrk1) Then
13381 xwrk = xdont(ilowt(icrs))
13382 Do ilow = 1, nord - 1
13383 If (xwrk <= xdont(irngt(ilow))) Then
13384 If (xwrk == xdont(irngt(ilow))) cycle insert1
13385 Exit
13386 End If
13387 End Do
13388 Do idcr = nord - 1, ilow, - 1
13389 irngt(idcr + 1) = irngt(idcr)
13390 End Do
13391 irngt(idcr + 1) = ilowt(icrs)
13392 xwrk1 = xdont(irngt(nord))
13393 End If
13394 End Do insert1
13395 !
13396 Return
13397 !
13398 ! ______________________________
13399 !
13400 Case (: -6)
13401 !
13402 ! last case: too many values in low part
13403 !
13404 ideb = jdeb + 1
13405 imil = min((jlow + ideb) / 2, nord)
13406 ifin = min(jlow, nord + 1)
13407 !
13408 ! One chooses a pivot from 1st, last, and middle values
13409 !
13410 If (xdont(ilowt(imil)) < xdont(ilowt(ideb))) Then
13411 iwrk = ilowt(ideb)
13412 ilowt(ideb) = ilowt(imil)
13413 ilowt(imil) = iwrk
13414 End If
13415 If (xdont(ilowt(imil)) > xdont(ilowt(ifin))) Then
13416 iwrk = ilowt(ifin)
13417 ilowt(ifin) = ilowt(imil)
13418 ilowt(imil) = iwrk
13419 If (xdont(ilowt(imil)) < xdont(ilowt(ideb))) Then
13420 iwrk = ilowt(ideb)
13421 ilowt(ideb) = ilowt(imil)
13422 ilowt(imil) = iwrk
13423 End If
13424 End If
13425 If (ifin <= 3) Exit
13426 !
13427 xpiv = xdont(ilowt(ideb)) + int(real(nord, sp) / real(jlow + nord, sp), i4) * &
13428 (xdont(ilowt(ifin)) - xdont(ilowt(1)))
13429 If (jdeb > 0) Then
13430 If (xpiv <= xpiv0) &
13431 xpiv = xpiv0 + int(real(2 * nord - jdeb, sp) / real(jlow + nord, sp), i4) * &
13432 (xdont(ilowt(ifin)) - xpiv0)
13433 Else
13434 ideb = 1
13435 End If
13436 !
13437 ! One takes values > XPIV to IHIGT
13438 ! However, we do not process the first values if we have been
13439 ! through the case when we did not have enough low values
13440 !
13441 jhig = 0
13442 ifin = jlow
13443 jlow = jdeb
13444 !
13445 If (xdont(ilowt(ifin)) > xpiv) Then
13446 icrs = jdeb
13447 lowloop4 : Do
13448 icrs = icrs + 1
13449 If (xdont(ilowt(icrs)) > xpiv) Then
13450 jhig = jhig + 1
13451 ihigt(jhig) = ilowt(icrs)
13452 If (icrs >= ifin) Exit
13453 Else
13454 xwrk1 = xdont(ilowt(icrs))
13455 Do ilow = ideb, jlow
13456 If (xwrk1 == xdont(ilowt(ilow))) &
13457 cycle lowloop4
13458 End Do
13459 jlow = jlow + 1
13460 ilowt(jlow) = ilowt(icrs)
13461 If (jlow >= nord) Exit
13462 End If
13463 End Do lowloop4
13464 !
13465 If (icrs < ifin) Then
13466 Do
13467 icrs = icrs + 1
13468 If (xdont(ilowt(icrs)) <= xpiv) Then
13469 jlow = jlow + 1
13470 ilowt(jlow) = ilowt(icrs)
13471 Else
13472 If (icrs >= ifin) Exit
13473 End If
13474 End Do
13475 End If
13476 Else
13477 lowloop5 : Do icrs = ideb, ifin
13478 If (xdont(ilowt(icrs)) > xpiv) Then
13479 jhig = jhig + 1
13480 ihigt(jhig) = ilowt(icrs)
13481 Else
13482 xwrk1 = xdont(ilowt(icrs))
13483 Do ilow = ideb, jlow
13484 If (xwrk1 == xdont(ilowt(ilow))) &
13485 cycle lowloop5
13486 End Do
13487 jlow = jlow + 1
13488 ilowt(jlow) = ilowt(icrs)
13489 If (jlow >= nord) Exit
13490 End If
13491 End Do lowloop5
13492 !
13493 Do icrs = icrs + 1, ifin
13494 If (xdont(ilowt(icrs)) <= xpiv) Then
13495 jlow = jlow + 1
13496 ilowt(jlow) = ilowt(icrs)
13497 End If
13498 End Do
13499 End If
13500 !
13501 End Select
13502 ! ______________________________
13503 !
13504 End Do
13505 !
13506 ! Now, we only need to complete ranking of the 1:NORD set
13507 ! Assuming NORD is small, we use a simple insertion sort
13508 !
13509 irngt(1) = ilowt(1)
13510 Do icrs = 2, nord
13511 iwrk = ilowt(icrs)
13512 xwrk = xdont(iwrk)
13513 Do idcr = icrs - 1, 1, - 1
13514 If (xwrk < xdont(irngt(idcr))) Then
13515 irngt(idcr + 1) = irngt(idcr)
13516 Else
13517 Exit
13518 End If
13519 End Do
13520 irngt(idcr + 1) = iwrk
13521 End Do
13522 Return
13523 !
13524 !
13525 End Subroutine i_unipar
13526
13527 Subroutine d_unirnk (XVALT, IRNGT, NUNI)
13528 ! __________________________________________________________
13529 ! UNIRNK = Merge-sort ranking of an array, with removal of
13530 ! duplicate entries.
13531 ! The routine is similar to pure merge-sort ranking, but on
13532 ! the last pass, it discards indices that correspond to
13533 ! duplicate entries.
13534 ! For performance reasons, the first 2 passes are taken
13535 ! out of the standard loop, and use dedicated coding.
13536 ! __________________________________________________________
13537 ! __________________________________________________________
13538 real(Kind = dp), Dimension (:), Intent (In) :: xvalt
13539 Integer(kind = i4), Dimension (:), Intent (Out) :: IRNGT
13540 Integer(kind = i4), Intent (Out) :: NUNI
13541 ! __________________________________________________________
13542 Integer(kind = i4), Dimension (SIZE(IRNGT)) :: JWRKT
13543 Integer(kind = i4) :: LMTNA, LMTNC, IRNG, IRNG1, IRNG2
13544 Integer(kind = i4) :: NVAL, IIND, IWRKD, IWRK, IWRKF, JINDA, IINDA, IINDB
13545 real(Kind = dp) :: xtst, xvala, xvalb
13546 !
13547 !
13548 nval = min(SIZE(xvalt), SIZE(irngt))
13549 nuni = nval
13550 !
13551 Select Case (nval)
13552 Case (: 0)
13553 Return
13554 Case (1)
13555 irngt(1) = 1
13556 Return
13557 Case Default
13558
13559 End Select
13560 !
13561 ! Fill-in the index array, creating ordered couples
13562 !
13563 Do iind = 2, nval, 2
13564 If (xvalt(iind - 1) < xvalt(iind)) Then
13565 irngt(iind - 1) = iind - 1
13566 irngt(iind) = iind
13567 Else
13568 irngt(iind - 1) = iind
13569 irngt(iind) = iind - 1
13570 End If
13571 End Do
13572 If (modulo(nval, 2) /= 0) Then
13573 irngt(nval) = nval
13574 End If
13575 !
13576 ! We will now have ordered subsets A - B - A - B - ...
13577 ! and merge A and B couples into C - C - ...
13578 !
13579 lmtna = 2
13580 lmtnc = 4
13581 !
13582 ! First iteration. The length of the ordered subsets goes from 2 to 4
13583 !
13584 Do
13585 If (nval <= 4) Exit
13586 !
13587 ! Loop on merges of A and B into C
13588 !
13589 Do iwrkd = 0, nval - 1, 4
13590 If ((iwrkd + 4) > nval) Then
13591 If ((iwrkd + 2) >= nval) Exit
13592 !
13593 ! 1 2 3
13594 !
13595 If (xvalt(irngt(iwrkd + 2)) <= xvalt(irngt(iwrkd + 3))) Exit
13596 !
13597 ! 1 3 2
13598 !
13599 If (xvalt(irngt(iwrkd + 1)) <= xvalt(irngt(iwrkd + 3))) Then
13600 irng2 = irngt(iwrkd + 2)
13601 irngt(iwrkd + 2) = irngt(iwrkd + 3)
13602 irngt(iwrkd + 3) = irng2
13603 !
13604 ! 3 1 2
13605 !
13606 Else
13607 irng1 = irngt(iwrkd + 1)
13608 irngt(iwrkd + 1) = irngt(iwrkd + 3)
13609 irngt(iwrkd + 3) = irngt(iwrkd + 2)
13610 irngt(iwrkd + 2) = irng1
13611 End If
13612 If (.true.) Exit ! Exit ! JM
13613 End If
13614 !
13615 ! 1 2 3 4
13616 !
13617 If (xvalt(irngt(iwrkd + 2)) <= xvalt(irngt(iwrkd + 3))) cycle
13618 !
13619 ! 1 3 x x
13620 !
13621 If (xvalt(irngt(iwrkd + 1)) <= xvalt(irngt(iwrkd + 3))) Then
13622 irng2 = irngt(iwrkd + 2)
13623 irngt(iwrkd + 2) = irngt(iwrkd + 3)
13624 If (xvalt(irng2) <= xvalt(irngt(iwrkd + 4))) Then
13625 ! 1 3 2 4
13626 irngt(iwrkd + 3) = irng2
13627 Else
13628 ! 1 3 4 2
13629 irngt(iwrkd + 3) = irngt(iwrkd + 4)
13630 irngt(iwrkd + 4) = irng2
13631 End If
13632 !
13633 ! 3 x x x
13634 !
13635 Else
13636 irng1 = irngt(iwrkd + 1)
13637 irng2 = irngt(iwrkd + 2)
13638 irngt(iwrkd + 1) = irngt(iwrkd + 3)
13639 If (xvalt(irng1) <= xvalt(irngt(iwrkd + 4))) Then
13640 irngt(iwrkd + 2) = irng1
13641 If (xvalt(irng2) <= xvalt(irngt(iwrkd + 4))) Then
13642 ! 3 1 2 4
13643 irngt(iwrkd + 3) = irng2
13644 Else
13645 ! 3 1 4 2
13646 irngt(iwrkd + 3) = irngt(iwrkd + 4)
13647 irngt(iwrkd + 4) = irng2
13648 End If
13649 Else
13650 ! 3 4 1 2
13651 irngt(iwrkd + 2) = irngt(iwrkd + 4)
13652 irngt(iwrkd + 3) = irng1
13653 irngt(iwrkd + 4) = irng2
13654 End If
13655 End If
13656 End Do
13657 !
13658 ! The Cs become As and Bs
13659 !
13660 lmtna = 4
13661 If (.true.) Exit ! Exit ! JM
13662 End Do
13663 !
13664 ! Iteration loop. Each time, the length of the ordered subsets
13665 ! is doubled.
13666 !
13667 Do
13668 If (2 * lmtna >= nval) Exit
13669 iwrkf = 0
13670 lmtnc = 2 * lmtnc
13671 !
13672 ! Loop on merges of A and B into C
13673 !
13674 Do
13675 iwrk = iwrkf
13676 iwrkd = iwrkf + 1
13677 jinda = iwrkf + lmtna
13678 iwrkf = iwrkf + lmtnc
13679 If (iwrkf >= nval) Then
13680 If (jinda >= nval) Exit
13681 iwrkf = nval
13682 End If
13683 iinda = 1
13684 iindb = jinda + 1
13685 !
13686 ! One steps in the C subset, that we create in the final rank array
13687 !
13688 ! Make a copy of the rank array for the iteration
13689 !
13690 jwrkt(1 : lmtna) = irngt(iwrkd : jinda)
13691 xvala = xvalt(jwrkt(iinda))
13692 xvalb = xvalt(irngt(iindb))
13693 !
13694 Do
13695 iwrk = iwrk + 1
13696 !
13697 ! We still have unprocessed values in both A and B
13698 !
13699 If (xvala > xvalb) Then
13700 irngt(iwrk) = irngt(iindb)
13701 iindb = iindb + 1
13702 If (iindb > iwrkf) Then
13703 ! Only A still with unprocessed values
13704 irngt(iwrk + 1 : iwrkf) = jwrkt(iinda : lmtna)
13705 Exit
13706 End If
13707 xvalb = xvalt(irngt(iindb))
13708 Else
13709 irngt(iwrk) = jwrkt(iinda)
13710 iinda = iinda + 1
13711 If (iinda > lmtna) exit! Only B still with unprocessed values
13712 xvala = xvalt(jwrkt(iinda))
13713 End If
13714 !
13715 End Do
13716 End Do
13717 !
13718 ! The Cs become As and Bs
13719 !
13720 lmtna = 2 * lmtna
13721 End Do
13722 !
13723 ! Last merge of A and B into C, with removal of duplicates.
13724 !
13725 iinda = 1
13726 iindb = lmtna + 1
13727 nuni = 0
13728 !
13729 ! One steps in the C subset, that we create in the final rank array
13730 !
13731 jwrkt(1 : lmtna) = irngt(1 : lmtna)
13732 If (iindb <= nval) Then
13733 xtst = nearless(min(xvalt(jwrkt(1)), xvalt(irngt(iindb))))
13734 Else
13735 xtst = nearless(xvalt(jwrkt(1)))
13736 end if
13737 Do iwrk = 1, nval
13738 !
13739 ! We still have unprocessed values in both A and B
13740 !
13741 If (iinda <= lmtna) Then
13742 If (iindb <= nval) Then
13743 If (xvalt(jwrkt(iinda)) > xvalt(irngt(iindb))) Then
13744 irng = irngt(iindb)
13745 iindb = iindb + 1
13746 Else
13747 irng = jwrkt(iinda)
13748 iinda = iinda + 1
13749 End If
13750 Else
13751 !
13752 ! Only A still with unprocessed values
13753 !
13754 irng = jwrkt(iinda)
13755 iinda = iinda + 1
13756 End If
13757 Else
13758 !
13759 ! Only B still with unprocessed values
13760 !
13761 irng = irngt(iwrk)
13762 End If
13763 If (xvalt(irng) > xtst) Then
13764 xtst = xvalt(irng)
13765 nuni = nuni + 1
13766 irngt(nuni) = irng
13767 End If
13768 !
13769 End Do
13770 !
13771 Return
13772 !
13773 End Subroutine d_unirnk
13774
13775 Subroutine r_unirnk (XVALT, IRNGT, NUNI)
13776 ! __________________________________________________________
13777 ! UNIRNK = Merge-sort ranking of an array, with removal of
13778 ! duplicate entries.
13779 ! The routine is similar to pure merge-sort ranking, but on
13780 ! the last pass, it discards indices that correspond to
13781 ! duplicate entries.
13782 ! For performance reasons, the first 2 passes are taken
13783 ! out of the standard loop, and use dedicated coding.
13784 ! __________________________________________________________
13785 ! __________________________________________________________
13786 Real(kind = sp), Dimension (:), Intent (In) :: xvalt
13787 Integer(kind = i4), Dimension (:), Intent (Out) :: IRNGT
13788 Integer(kind = i4), Intent (Out) :: NUNI
13789 ! __________________________________________________________
13790 Integer(kind = i4), Dimension (SIZE(IRNGT)) :: JWRKT
13791 Integer(kind = i4) :: LMTNA, LMTNC, IRNG, IRNG1, IRNG2
13792 Integer(kind = i4) :: NVAL, IIND, IWRKD, IWRK, IWRKF, JINDA, IINDA, IINDB
13793 Real(kind = sp) :: xtst, xvala, xvalb
13794 !
13795 !
13796 nval = min(SIZE(xvalt), SIZE(irngt))
13797 nuni = nval
13798 !
13799 Select Case (nval)
13800 Case (: 0)
13801 Return
13802 Case (1)
13803 irngt(1) = 1
13804 Return
13805 Case Default
13806
13807 End Select
13808 !
13809 ! Fill-in the index array, creating ordered couples
13810 !
13811 Do iind = 2, nval, 2
13812 If (xvalt(iind - 1) < xvalt(iind)) Then
13813 irngt(iind - 1) = iind - 1
13814 irngt(iind) = iind
13815 Else
13816 irngt(iind - 1) = iind
13817 irngt(iind) = iind - 1
13818 End If
13819 End Do
13820 If (modulo(nval, 2) /= 0) Then
13821 irngt(nval) = nval
13822 End If
13823 !
13824 ! We will now have ordered subsets A - B - A - B - ...
13825 ! and merge A and B couples into C - C - ...
13826 !
13827 lmtna = 2
13828 lmtnc = 4
13829 !
13830 ! First iteration. The length of the ordered subsets goes from 2 to 4
13831 !
13832 Do
13833 If (nval <= 4) Exit
13834 !
13835 ! Loop on merges of A and B into C
13836 !
13837 Do iwrkd = 0, nval - 1, 4
13838 If ((iwrkd + 4) > nval) Then
13839 If ((iwrkd + 2) >= nval) Exit
13840 !
13841 ! 1 2 3
13842 !
13843 If (xvalt(irngt(iwrkd + 2)) <= xvalt(irngt(iwrkd + 3))) Exit
13844 !
13845 ! 1 3 2
13846 !
13847 If (xvalt(irngt(iwrkd + 1)) <= xvalt(irngt(iwrkd + 3))) Then
13848 irng2 = irngt(iwrkd + 2)
13849 irngt(iwrkd + 2) = irngt(iwrkd + 3)
13850 irngt(iwrkd + 3) = irng2
13851 !
13852 ! 3 1 2
13853 !
13854 Else
13855 irng1 = irngt(iwrkd + 1)
13856 irngt(iwrkd + 1) = irngt(iwrkd + 3)
13857 irngt(iwrkd + 3) = irngt(iwrkd + 2)
13858 irngt(iwrkd + 2) = irng1
13859 End If
13860 If (.true.) Exit ! Exit ! JM
13861 End If
13862 !
13863 ! 1 2 3 4
13864 !
13865 If (xvalt(irngt(iwrkd + 2)) <= xvalt(irngt(iwrkd + 3))) cycle
13866 !
13867 ! 1 3 x x
13868 !
13869 If (xvalt(irngt(iwrkd + 1)) <= xvalt(irngt(iwrkd + 3))) Then
13870 irng2 = irngt(iwrkd + 2)
13871 irngt(iwrkd + 2) = irngt(iwrkd + 3)
13872 If (xvalt(irng2) <= xvalt(irngt(iwrkd + 4))) Then
13873 ! 1 3 2 4
13874 irngt(iwrkd + 3) = irng2
13875 Else
13876 ! 1 3 4 2
13877 irngt(iwrkd + 3) = irngt(iwrkd + 4)
13878 irngt(iwrkd + 4) = irng2
13879 End If
13880 !
13881 ! 3 x x x
13882 !
13883 Else
13884 irng1 = irngt(iwrkd + 1)
13885 irng2 = irngt(iwrkd + 2)
13886 irngt(iwrkd + 1) = irngt(iwrkd + 3)
13887 If (xvalt(irng1) <= xvalt(irngt(iwrkd + 4))) Then
13888 irngt(iwrkd + 2) = irng1
13889 If (xvalt(irng2) <= xvalt(irngt(iwrkd + 4))) Then
13890 ! 3 1 2 4
13891 irngt(iwrkd + 3) = irng2
13892 Else
13893 ! 3 1 4 2
13894 irngt(iwrkd + 3) = irngt(iwrkd + 4)
13895 irngt(iwrkd + 4) = irng2
13896 End If
13897 Else
13898 ! 3 4 1 2
13899 irngt(iwrkd + 2) = irngt(iwrkd + 4)
13900 irngt(iwrkd + 3) = irng1
13901 irngt(iwrkd + 4) = irng2
13902 End If
13903 End If
13904 End Do
13905 !
13906 ! The Cs become As and Bs
13907 !
13908 lmtna = 4
13909 If (.true.) Exit ! Exit ! JM
13910 End Do
13911 !
13912 ! Iteration loop. Each time, the length of the ordered subsets
13913 ! is doubled.
13914 !
13915 Do
13916 If (2 * lmtna >= nval) Exit
13917 iwrkf = 0
13918 lmtnc = 2 * lmtnc
13919 !
13920 ! Loop on merges of A and B into C
13921 !
13922 Do
13923 iwrk = iwrkf
13924 iwrkd = iwrkf + 1
13925 jinda = iwrkf + lmtna
13926 iwrkf = iwrkf + lmtnc
13927 If (iwrkf >= nval) Then
13928 If (jinda >= nval) Exit
13929 iwrkf = nval
13930 End If
13931 iinda = 1
13932 iindb = jinda + 1
13933 !
13934 ! One steps in the C subset, that we create in the final rank array
13935 !
13936 ! Make a copy of the rank array for the iteration
13937 !
13938 jwrkt(1 : lmtna) = irngt(iwrkd : jinda)
13939 xvala = xvalt(jwrkt(iinda))
13940 xvalb = xvalt(irngt(iindb))
13941 !
13942 Do
13943 iwrk = iwrk + 1
13944 !
13945 ! We still have unprocessed values in both A and B
13946 !
13947 If (xvala > xvalb) Then
13948 irngt(iwrk) = irngt(iindb)
13949 iindb = iindb + 1
13950 If (iindb > iwrkf) Then
13951 ! Only A still with unprocessed values
13952 irngt(iwrk + 1 : iwrkf) = jwrkt(iinda : lmtna)
13953 Exit
13954 End If
13955 xvalb = xvalt(irngt(iindb))
13956 Else
13957 irngt(iwrk) = jwrkt(iinda)
13958 iinda = iinda + 1
13959 If (iinda > lmtna) exit! Only B still with unprocessed values
13960 xvala = xvalt(jwrkt(iinda))
13961 End If
13962 !
13963 End Do
13964 End Do
13965 !
13966 ! The Cs become As and Bs
13967 !
13968 lmtna = 2 * lmtna
13969 End Do
13970 !
13971 ! Last merge of A and B into C, with removal of duplicates.
13972 !
13973 iinda = 1
13974 iindb = lmtna + 1
13975 nuni = 0
13976 !
13977 ! One steps in the C subset, that we create in the final rank array
13978 !
13979 jwrkt(1 : lmtna) = irngt(1 : lmtna)
13980 If (iindb <= nval) Then
13981 xtst = nearless(min(xvalt(jwrkt(1)), xvalt(irngt(iindb))))
13982 Else
13983 xtst = nearless(xvalt(jwrkt(1)))
13984 end if
13985 Do iwrk = 1, nval
13986 !
13987 ! We still have unprocessed values in both A and B
13988 !
13989 If (iinda <= lmtna) Then
13990 If (iindb <= nval) Then
13991 If (xvalt(jwrkt(iinda)) > xvalt(irngt(iindb))) Then
13992 irng = irngt(iindb)
13993 iindb = iindb + 1
13994 Else
13995 irng = jwrkt(iinda)
13996 iinda = iinda + 1
13997 End If
13998 Else
13999 !
14000 ! Only A still with unprocessed values
14001 !
14002 irng = jwrkt(iinda)
14003 iinda = iinda + 1
14004 End If
14005 Else
14006 !
14007 ! Only B still with unprocessed values
14008 !
14009 irng = irngt(iwrk)
14010 End If
14011 If (xvalt(irng) > xtst) Then
14012 xtst = xvalt(irng)
14013 nuni = nuni + 1
14014 irngt(nuni) = irng
14015 End If
14016 !
14017 End Do
14018 !
14019 Return
14020 !
14021 End Subroutine r_unirnk
14022
14023 Subroutine i_unirnk (XVALT, IRNGT, NUNI)
14024 ! __________________________________________________________
14025 ! UNIRNK = Merge-sort ranking of an array, with removal of
14026 ! duplicate entries.
14027 ! The routine is similar to pure merge-sort ranking, but on
14028 ! the last pass, it discards indices that correspond to
14029 ! duplicate entries.
14030 ! For performance reasons, the first 2 passes are taken
14031 ! out of the standard loop, and use dedicated coding.
14032 ! __________________________________________________________
14033 ! __________________________________________________________
14034 Integer(kind = i4), Dimension (:), Intent (In) :: XVALT
14035 Integer(kind = i4), Dimension (:), Intent (Out) :: IRNGT
14036 Integer(kind = i4), Intent (Out) :: NUNI
14037 ! __________________________________________________________
14038 Integer(kind = i4), Dimension (SIZE(IRNGT)) :: JWRKT
14039 Integer(kind = i4) :: LMTNA, LMTNC, IRNG, IRNG1, IRNG2
14040 Integer(kind = i4) :: NVAL, IIND, IWRKD, IWRK, IWRKF, JINDA, IINDA, IINDB
14041 Integer(kind = i4) :: XTST, XVALA, XVALB
14042 !
14043 !
14044 nval = min(SIZE(xvalt), SIZE(irngt))
14045 nuni = nval
14046 !
14047 Select Case (nval)
14048 Case (: 0)
14049 Return
14050 Case (1)
14051 irngt(1) = 1
14052 Return
14053 Case Default
14054
14055 End Select
14056 !
14057 ! Fill-in the index array, creating ordered couples
14058 !
14059 Do iind = 2, nval, 2
14060 If (xvalt(iind - 1) < xvalt(iind)) Then
14061 irngt(iind - 1) = iind - 1
14062 irngt(iind) = iind
14063 Else
14064 irngt(iind - 1) = iind
14065 irngt(iind) = iind - 1
14066 End If
14067 End Do
14068 If (modulo(nval, 2) /= 0) Then
14069 irngt(nval) = nval
14070 End If
14071 !
14072 ! We will now have ordered subsets A - B - A - B - ...
14073 ! and merge A and B couples into C - C - ...
14074 !
14075 lmtna = 2
14076 lmtnc = 4
14077 !
14078 ! First iteration. The length of the ordered subsets goes from 2 to 4
14079 !
14080 Do
14081 If (nval <= 4) Exit
14082 !
14083 ! Loop on merges of A and B into C
14084 !
14085 Do iwrkd = 0, nval - 1, 4
14086 If ((iwrkd + 4) > nval) Then
14087 If ((iwrkd + 2) >= nval) Exit
14088 !
14089 ! 1 2 3
14090 !
14091 If (xvalt(irngt(iwrkd + 2)) <= xvalt(irngt(iwrkd + 3))) Exit
14092 !
14093 ! 1 3 2
14094 !
14095 If (xvalt(irngt(iwrkd + 1)) <= xvalt(irngt(iwrkd + 3))) Then
14096 irng2 = irngt(iwrkd + 2)
14097 irngt(iwrkd + 2) = irngt(iwrkd + 3)
14098 irngt(iwrkd + 3) = irng2
14099 !
14100 ! 3 1 2
14101 !
14102 Else
14103 irng1 = irngt(iwrkd + 1)
14104 irngt(iwrkd + 1) = irngt(iwrkd + 3)
14105 irngt(iwrkd + 3) = irngt(iwrkd + 2)
14106 irngt(iwrkd + 2) = irng1
14107 End If
14108 If (.true.) Exit ! Exit ! JM
14109 End If
14110 !
14111 ! 1 2 3 4
14112 !
14113 If (xvalt(irngt(iwrkd + 2)) <= xvalt(irngt(iwrkd + 3))) cycle
14114 !
14115 ! 1 3 x x
14116 !
14117 If (xvalt(irngt(iwrkd + 1)) <= xvalt(irngt(iwrkd + 3))) Then
14118 irng2 = irngt(iwrkd + 2)
14119 irngt(iwrkd + 2) = irngt(iwrkd + 3)
14120 If (xvalt(irng2) <= xvalt(irngt(iwrkd + 4))) Then
14121 ! 1 3 2 4
14122 irngt(iwrkd + 3) = irng2
14123 Else
14124 ! 1 3 4 2
14125 irngt(iwrkd + 3) = irngt(iwrkd + 4)
14126 irngt(iwrkd + 4) = irng2
14127 End If
14128 !
14129 ! 3 x x x
14130 !
14131 Else
14132 irng1 = irngt(iwrkd + 1)
14133 irng2 = irngt(iwrkd + 2)
14134 irngt(iwrkd + 1) = irngt(iwrkd + 3)
14135 If (xvalt(irng1) <= xvalt(irngt(iwrkd + 4))) Then
14136 irngt(iwrkd + 2) = irng1
14137 If (xvalt(irng2) <= xvalt(irngt(iwrkd + 4))) Then
14138 ! 3 1 2 4
14139 irngt(iwrkd + 3) = irng2
14140 Else
14141 ! 3 1 4 2
14142 irngt(iwrkd + 3) = irngt(iwrkd + 4)
14143 irngt(iwrkd + 4) = irng2
14144 End If
14145 Else
14146 ! 3 4 1 2
14147 irngt(iwrkd + 2) = irngt(iwrkd + 4)
14148 irngt(iwrkd + 3) = irng1
14149 irngt(iwrkd + 4) = irng2
14150 End If
14151 End If
14152 End Do
14153 !
14154 ! The Cs become As and Bs
14155 !
14156 lmtna = 4
14157 If (.true.) Exit ! Exit ! JM
14158 End Do
14159 !
14160 ! Iteration loop. Each time, the length of the ordered subsets
14161 ! is doubled.
14162 !
14163 Do
14164 If (2 * lmtna >= nval) Exit
14165 iwrkf = 0
14166 lmtnc = 2 * lmtnc
14167 !
14168 ! Loop on merges of A and B into C
14169 !
14170 Do
14171 iwrk = iwrkf
14172 iwrkd = iwrkf + 1
14173 jinda = iwrkf + lmtna
14174 iwrkf = iwrkf + lmtnc
14175 If (iwrkf >= nval) Then
14176 If (jinda >= nval) Exit
14177 iwrkf = nval
14178 End If
14179 iinda = 1
14180 iindb = jinda + 1
14181 !
14182 ! One steps in the C subset, that we create in the final rank array
14183 !
14184 ! Make a copy of the rank array for the iteration
14185 !
14186 jwrkt(1 : lmtna) = irngt(iwrkd : jinda)
14187 xvala = xvalt(jwrkt(iinda))
14188 xvalb = xvalt(irngt(iindb))
14189 !
14190 Do
14191 iwrk = iwrk + 1
14192 !
14193 ! We still have unprocessed values in both A and B
14194 !
14195 If (xvala > xvalb) Then
14196 irngt(iwrk) = irngt(iindb)
14197 iindb = iindb + 1
14198 If (iindb > iwrkf) Then
14199 ! Only A still with unprocessed values
14200 irngt(iwrk + 1 : iwrkf) = jwrkt(iinda : lmtna)
14201 Exit
14202 End If
14203 xvalb = xvalt(irngt(iindb))
14204 Else
14205 irngt(iwrk) = jwrkt(iinda)
14206 iinda = iinda + 1
14207 If (iinda > lmtna) exit! Only B still with unprocessed values
14208 xvala = xvalt(jwrkt(iinda))
14209 End If
14210 !
14211 End Do
14212 End Do
14213 !
14214 ! The Cs become As and Bs
14215 !
14216 lmtna = 2 * lmtna
14217 End Do
14218 !
14219 ! Last merge of A and B into C, with removal of duplicates.
14220 !
14221 iinda = 1
14222 iindb = lmtna + 1
14223 nuni = 0
14224 !
14225 ! One steps in the C subset, that we create in the final rank array
14226 !
14227 jwrkt(1 : lmtna) = irngt(1 : lmtna)
14228 If (iindb <= nval) Then
14229 xtst = nearless(min(xvalt(jwrkt(1)), xvalt(irngt(iindb))))
14230 Else
14231 xtst = nearless(xvalt(jwrkt(1)))
14232 end if
14233 Do iwrk = 1, nval
14234 !
14235 ! We still have unprocessed values in both A and B
14236 !
14237 If (iinda <= lmtna) Then
14238 If (iindb <= nval) Then
14239 If (xvalt(jwrkt(iinda)) > xvalt(irngt(iindb))) Then
14240 irng = irngt(iindb)
14241 iindb = iindb + 1
14242 Else
14243 irng = jwrkt(iinda)
14244 iinda = iinda + 1
14245 End If
14246 Else
14247 !
14248 ! Only A still with unprocessed values
14249 !
14250 irng = jwrkt(iinda)
14251 iinda = iinda + 1
14252 End If
14253 Else
14254 !
14255 ! Only B still with unprocessed values
14256 !
14257 irng = irngt(iwrk)
14258 End If
14259 If (xvalt(irng) > xtst) Then
14260 xtst = xvalt(irng)
14261 nuni = nuni + 1
14262 irngt(nuni) = irng
14263 End If
14264 !
14265 End Do
14266 !
14267 Return
14268 !
14269 End Subroutine i_unirnk
14270
14271
14272 Subroutine d_unista (XDONT, NUNI)
14273 ! UNISTA = (Stable unique) Removes duplicates from an array,
14274 ! leaving unique entries in the order of their first
14275 ! appearance in the initial set.
14276 ! Michel Olagnon - Feb. 2000
14277 ! __________________________________________________________
14278 ! __________________________________________________________
14279 real(kind = dp), Dimension (:), Intent (InOut) :: xdont
14280 Integer(kind = i4), Intent (Out) :: NUNI
14281 ! __________________________________________________________
14282 !
14283 Integer(kind = i4), Dimension (Size(XDONT)) :: IWRKT
14284 Logical, Dimension (Size(XDONT)) :: IFMPTYT
14285 Integer(kind = i4) :: ICRS
14286 ! __________________________________________________________
14287 Call uniinv (xdont, iwrkt)
14288 ifmptyt = .true.
14289 nuni = 0
14290 Do icrs = 1, Size(xdont)
14291 If (ifmptyt(iwrkt(icrs))) Then
14292 ifmptyt(iwrkt(icrs)) = .false.
14293 nuni = nuni + 1
14294 xdont(nuni) = xdont(icrs)
14295 End If
14296 End Do
14297 Return
14298 !
14299 End Subroutine d_unista
14300
14301 Subroutine r_unista (XDONT, NUNI)
14302 ! UNISTA = (Stable unique) Removes duplicates from an array,
14303 ! leaving unique entries in the order of their first
14304 ! appearance in the initial set.
14305 ! Michel Olagnon - Feb. 2000
14306 ! __________________________________________________________
14307 ! _________________________________________________________
14308 Real(kind = sp), Dimension (:), Intent (InOut) :: xdont
14309 Integer(kind = i4), Intent (Out) :: NUNI
14310 ! __________________________________________________________
14311 !
14312 Integer(kind = i4), Dimension (Size(XDONT)) :: IWRKT
14313 Logical, Dimension (Size(XDONT)) :: IFMPTYT
14314 Integer(kind = i4) :: ICRS
14315 ! __________________________________________________________
14316 Call uniinv (xdont, iwrkt)
14317 ifmptyt = .true.
14318 nuni = 0
14319 Do icrs = 1, Size(xdont)
14320 If (ifmptyt(iwrkt(icrs))) Then
14321 ifmptyt(iwrkt(icrs)) = .false.
14322 nuni = nuni + 1
14323 xdont(nuni) = xdont(icrs)
14324 End If
14325 End Do
14326 Return
14327 !
14328 End Subroutine r_unista
14329
14330 Subroutine i_unista (XDONT, NUNI)
14331 ! UNISTA = (Stable unique) Removes duplicates from an array,
14332 ! leaving unique entries in the order of their first
14333 ! appearance in the initial set.
14334 ! Michel Olagnon - Feb. 2000
14335 ! __________________________________________________________
14336 ! __________________________________________________________
14337 Integer(kind = i4), Dimension (:), Intent (InOut) :: XDONT
14338 Integer(kind = i4), Intent (Out) :: NUNI
14339 ! __________________________________________________________
14340 !
14341 Integer(kind = i4), Dimension (Size(XDONT)) :: IWRKT
14342 Logical, Dimension (Size(XDONT)) :: IFMPTYT
14343 Integer(kind = i4) :: ICRS
14344 ! __________________________________________________________
14345 Call uniinv (xdont, iwrkt)
14346 ifmptyt = .true.
14347 nuni = 0
14348 Do icrs = 1, Size(xdont)
14349 If (ifmptyt(iwrkt(icrs))) Then
14350 ifmptyt(iwrkt(icrs)) = .false.
14351 nuni = nuni + 1
14352 xdont(nuni) = xdont(icrs)
14353 End If
14354 End Do
14355 Return
14356 !
14357 End Subroutine i_unista
14358
14359 Recursive Function d_valmed (XDONT) Result (res_med)
14360 ! Finds the median of XDONT using the recursive procedure
14361 ! described in Knuth, The Art of Computer Programming,
14362 ! vol. 3, 5.3.3 - This procedure is linear in time, and
14363 ! does not require to be able to interpolate in the
14364 ! set as the one used in INDNTH. It also has better worst
14365 ! case behavior than INDNTH, but is about 30% slower in
14366 ! average for random uniformly distributed values.
14367 ! __________________________________________________________
14368 ! __________________________________________________________
14369 real(kind = dp), Dimension (:), Intent (In) :: xdont
14370 real(kind = dp) :: res_med
14371 ! __________________________________________________________
14372 real(kind = dp), Parameter :: xhuge = huge(xdont)
14373 real(kind = dp), Dimension (SIZE(XDONT) + 6) :: xwrkt
14374 real(kind = dp) :: xwrk, xwrk1, xmed7
14375 !
14376 Integer(kind = i4), Dimension ((SIZE(XDONT) + 6) / 7) :: ISTRT, IENDT, IMEDT
14377 Integer(kind = i4) :: NDON, NTRI, NMED, NORD, NEQU, NLEQ, IMED, IDON, IDON1
14378 Integer(kind = i4) :: IDEB, IWRK, IDCR, ICRS, ICRS1, ICRS2, IMED1
14379 !
14380 ndon = SIZE (xdont)
14381 nmed = (ndon + 1) / 2
14382 ! write(unit=*,fmt=*) NMED, NDON
14383 !
14384 ! If the number of values is small, then use insertion sort
14385 !
14386 If (ndon < 35) Then
14387 !
14388 ! Bring minimum to first location to save test in decreasing loop
14389 !
14390 idcr = ndon
14391 If (xdont(1) < xdont(ndon)) Then
14392 xwrk = xdont(1)
14393 xwrkt(idcr) = xdont(idcr)
14394 Else
14395 xwrk = xdont(idcr)
14396 xwrkt(idcr) = xdont(1)
14397 end if
14398 Do iwrk = 1, ndon - 2
14399 idcr = idcr - 1
14400 xwrk1 = xdont(idcr)
14401 If (xwrk1 < xwrk) Then
14402 xwrkt(idcr) = xwrk
14403 xwrk = xwrk1
14404 Else
14405 xwrkt(idcr) = xwrk1
14406 end if
14407 End Do
14408 xwrkt(1) = xwrk
14409 !
14410 ! Sort the first half, until we have NMED sorted values
14411 !
14412 Do icrs = 3, nmed
14413 xwrk = xwrkt(icrs)
14414 idcr = icrs - 1
14415 Do
14416 If (xwrk >= xwrkt(idcr)) Exit
14417 xwrkt(idcr + 1) = xwrkt(idcr)
14418 idcr = idcr - 1
14419 End Do
14420 xwrkt(idcr + 1) = xwrk
14421 End Do
14422 !
14423 ! Insert any value less than the current median in the first half
14424 !
14425 Do icrs = nmed + 1, ndon
14426 xwrk = xwrkt(icrs)
14427 If (xwrk < xwrkt(nmed)) Then
14428 idcr = nmed - 1
14429 Do
14430 If (xwrk >= xwrkt(idcr)) Exit
14431 xwrkt(idcr + 1) = xwrkt(idcr)
14432 idcr = idcr - 1
14433 End Do
14434 xwrkt(idcr + 1) = xwrk
14435 End If
14436 End Do
14437 res_med = xwrkt(nmed)
14438 Return
14439 End If
14440 !
14441 ! Make sorted subsets of 7 elements
14442 ! This is done by a variant of insertion sort where a first
14443 ! pass is used to bring the smallest element to the first position
14444 ! decreasing disorder at the same time, so that we may remove
14445 ! remove the loop test in the insertion loop.
14446 !
14447 DO ideb = 1, ndon - 6, 7
14448 idcr = ideb + 6
14449 If (xdont(ideb) < xdont(idcr)) Then
14450 xwrk = xdont(ideb)
14451 xwrkt(idcr) = xdont(idcr)
14452 Else
14453 xwrk = xdont(idcr)
14454 xwrkt(idcr) = xdont(ideb)
14455 end if
14456 Do iwrk = 1, 5
14457 idcr = idcr - 1
14458 xwrk1 = xdont(idcr)
14459 If (xwrk1 < xwrk) Then
14460 xwrkt(idcr) = xwrk
14461 xwrk = xwrk1
14462 Else
14463 xwrkt(idcr) = xwrk1
14464 end if
14465 End Do
14466 xwrkt(ideb) = xwrk
14467 Do icrs = ideb + 2, ideb + 6
14468 xwrk = xwrkt(icrs)
14469 If (xwrk < xwrkt(icrs - 1)) Then
14470 xwrkt(icrs) = xwrkt(icrs - 1)
14471 idcr = icrs - 1
14472 xwrk1 = xwrkt(idcr - 1)
14473 Do
14474 If (xwrk >= xwrk1) Exit
14475 xwrkt(idcr) = xwrk1
14476 idcr = idcr - 1
14477 xwrk1 = xwrkt(idcr - 1)
14478 End Do
14479 xwrkt(idcr) = xwrk
14480 end if
14481 End Do
14482 End Do
14483 !
14484 ! Add-up alternatively + and - HUGE values to make the number of data
14485 ! an exact multiple of 7.
14486 !
14487 ideb = 7 * (ndon / 7)
14488 ntri = ndon
14489 If (ideb < ndon) Then
14490 !
14491 xwrk1 = xhuge
14492 Do icrs = ideb + 1, ideb + 7
14493 If (icrs <= ndon) Then
14494 xwrkt(icrs) = xdont(icrs)
14495 Else
14496 If (ne(xwrk1, xhuge)) nmed = nmed + 1
14497 xwrkt(icrs) = xwrk1
14498 xwrk1 = - xwrk1
14499 end if
14500 End Do
14501 !
14502 Do icrs = ideb + 2, ideb + 7
14503 xwrk = xwrkt(icrs)
14504 Do idcr = icrs - 1, ideb + 1, - 1
14505 If (xwrk >= xwrkt(idcr)) Exit
14506 xwrkt(idcr + 1) = xwrkt(idcr)
14507 End Do
14508 xwrkt(idcr + 1) = xwrk
14509 End Do
14510 !
14511 ntri = ideb + 7
14512 End If
14513 !
14514 ! Make the set of the indices of median values of each sorted subset
14515 !
14516 idon1 = 0
14517 Do idon = 1, ntri, 7
14518 idon1 = idon1 + 1
14519 imedt(idon1) = idon + 3
14520 End Do
14521 !
14522 ! Find XMED7, the median of the medians
14523 !
14524 xmed7 = d_valmed(xwrkt(imedt))
14525 !
14526 ! Count how many values are not higher than (and how many equal to) XMED7
14527 ! This number is at least 4 * 1/2 * (N/7) : 4 values in each of the
14528 ! subsets where the median is lower than the median of medians. For similar
14529 ! reasons, we also have at least 2N/7 values not lower than XMED7. At the
14530 ! same time, we find in each subset the index of the last value < XMED7,
14531 ! and that of the first > XMED7. These indices will be used to restrict the
14532 ! search for the median as the Kth element in the subset (> or <) where
14533 ! we know it to be.
14534 !
14535 idon1 = 1
14536 nleq = 0
14537 nequ = 0
14538 Do idon = 1, ntri, 7
14539 imed = idon + 3
14540 If (xwrkt(imed) > xmed7) Then
14541 imed = imed - 2
14542 If (xwrkt(imed) > xmed7) Then
14543 imed = imed - 1
14544 Else If (xwrkt(imed) < xmed7) Then
14545 imed = imed + 1
14546 end if
14547 Else If (xwrkt(imed) < xmed7) Then
14548 imed = imed + 2
14549 If (xwrkt(imed) > xmed7) Then
14550 imed = imed - 1
14551 Else If (xwrkt(imed) < xmed7) Then
14552 imed = imed + 1
14553 end if
14554 end if
14555 If (xwrkt(imed) > xmed7) Then
14556 nleq = nleq + imed - idon
14557 iendt(idon1) = imed - 1
14558 istrt(idon1) = imed
14559 Else If (xwrkt(imed) < xmed7) Then
14560 nleq = nleq + imed - idon + 1
14561 iendt(idon1) = imed
14562 istrt(idon1) = imed + 1
14563 Else ! If (XWRKT (IMED) == XMED7)
14564 nleq = nleq + imed - idon + 1
14565 nequ = nequ + 1
14566 iendt(idon1) = imed - 1
14567 Do imed1 = imed - 1, idon, -1
14568 If (eq(xwrkt(imed1), xmed7)) Then
14569 nequ = nequ + 1
14570 iendt(idon1) = imed1 - 1
14571 Else
14572 Exit
14573 End If
14574 End Do
14575 istrt(idon1) = imed + 1
14576 Do imed1 = imed + 1, idon + 6
14577 If (eq(xwrkt(imed1), xmed7)) Then
14578 nequ = nequ + 1
14579 nleq = nleq + 1
14580 istrt(idon1) = imed1 + 1
14581 Else
14582 Exit
14583 End If
14584 End Do
14585 end if
14586 idon1 = idon1 + 1
14587 End Do
14588 !
14589 ! Carry out a partial insertion sort to find the Kth smallest of the
14590 ! large values, or the Kth largest of the small values, according to
14591 ! what is needed.
14592 !
14593 If (nleq - nequ + 1 <= nmed) Then
14594 If (nleq < nmed) Then ! Not enough low values
14595 xwrk1 = xhuge
14596 nord = nmed - nleq
14597 idon1 = 0
14598 icrs1 = 1
14599 icrs2 = 0
14600 idcr = 0
14601 Do idon = 1, ntri, 7
14602 idon1 = idon1 + 1
14603 If (icrs2 < nord) Then
14604 Do icrs = istrt(idon1), idon + 6
14605 If (xwrkt(icrs) < xwrk1) Then
14606 xwrk = xwrkt(icrs)
14607 Do idcr = icrs1 - 1, 1, - 1
14608 If (xwrk >= xwrkt(idcr)) Exit
14609 xwrkt(idcr + 1) = xwrkt(idcr)
14610 End Do
14611 xwrkt(idcr + 1) = xwrk
14612 xwrk1 = xwrkt(icrs1)
14613 Else
14614 If (icrs2 < nord) Then
14615 xwrkt(icrs1) = xwrkt(icrs)
14616 xwrk1 = xwrkt(icrs1)
14617 end if
14618 End If
14619 icrs1 = min(nord, icrs1 + 1)
14620 icrs2 = min(nord, icrs2 + 1)
14621 End Do
14622 Else
14623 Do icrs = istrt(idon1), idon + 6
14624 If (xwrkt(icrs) >= xwrk1) Exit
14625 xwrk = xwrkt(icrs)
14626 Do idcr = icrs1 - 1, 1, - 1
14627 If (xwrk >= xwrkt(idcr)) Exit
14628 xwrkt(idcr + 1) = xwrkt(idcr)
14629 End Do
14630 xwrkt(idcr + 1) = xwrk
14631 xwrk1 = xwrkt(icrs1)
14632 End Do
14633 End If
14634 End Do
14635 res_med = xwrk1
14636 Return
14637 Else
14638 res_med = xmed7
14639 Return
14640 End If
14641 Else ! If (NLEQ > NMED)
14642 ! Not enough high values
14643 xwrk1 = -xhuge
14644 nord = nleq - nequ - nmed + 1
14645 idon1 = 0
14646 icrs1 = 1
14647 icrs2 = 0
14648 Do idon = 1, ntri, 7
14649 idon1 = idon1 + 1
14650 If (icrs2 < nord) Then
14651 !
14652 Do icrs = idon, iendt(idon1)
14653 If (xwrkt(icrs) > xwrk1) Then
14654 xwrk = xwrkt(icrs)
14655 idcr = icrs1 - 1
14656 Do idcr = icrs1 - 1, 1, - 1
14657 If (xwrk <= xwrkt(idcr)) Exit
14658 xwrkt(idcr + 1) = xwrkt(idcr)
14659 End Do
14660 xwrkt(idcr + 1) = xwrk
14661 xwrk1 = xwrkt(icrs1)
14662 Else
14663 If (icrs2 < nord) Then
14664 xwrkt(icrs1) = xwrkt(icrs)
14665 xwrk1 = xwrkt(icrs1)
14666 End If
14667 End If
14668 icrs1 = min(nord, icrs1 + 1)
14669 icrs2 = min(nord, icrs2 + 1)
14670 End Do
14671 Else
14672 Do icrs = iendt(idon1), idon, -1
14673 If (xwrkt(icrs) > xwrk1) Then
14674 xwrk = xwrkt(icrs)
14675 idcr = icrs1 - 1
14676 Do idcr = icrs1 - 1, 1, - 1
14677 If (xwrk <= xwrkt(idcr)) Exit
14678 xwrkt(idcr + 1) = xwrkt(idcr)
14679 End Do
14680 xwrkt(idcr + 1) = xwrk
14681 xwrk1 = xwrkt(icrs1)
14682 Else
14683 Exit
14684 End If
14685 End Do
14686 end if
14687 End Do
14688 !
14689 res_med = xwrk1
14690 Return
14691 End If
14692 !
14693 End Function d_valmed
14694
14695 Recursive Function r_valmed (XDONT) Result (res_med)
14696 ! Finds the median of XDONT using the recursive procedure
14697 ! described in Knuth, The Art of Computer Programming,
14698 ! vol. 3, 5.3.3 - This procedure is linear in time, and
14699 ! does not require to be able to interpolate in the
14700 ! set as the one used in INDNTH. It also has better worst
14701 ! case behavior than INDNTH, but is about 30% slower in
14702 ! average for random uniformly distributed values.
14703 ! __________________________________________________________
14704 ! _________________________________________________________
14705 Real(kind = sp), Dimension (:), Intent (In) :: xdont
14706 Real(kind = sp) :: res_med
14707 ! __________________________________________________________
14708 Real(kind = sp), Parameter :: xhuge = huge(xdont)
14709 Real(kind = sp), Dimension (SIZE(XDONT) + 6) :: xwrkt
14710 Real(kind = sp) :: xwrk, xwrk1, xmed7
14711 !
14712 Integer(kind = i4), Dimension ((SIZE(XDONT) + 6) / 7) :: ISTRT, IENDT, IMEDT
14713 Integer(kind = i4) :: NDON, NTRI, NMED, NORD, NEQU, NLEQ, IMED, IDON, IDON1
14714 Integer(kind = i4) :: IDEB, IWRK, IDCR, ICRS, ICRS1, ICRS2, IMED1
14715 !
14716 ndon = SIZE (xdont)
14717 nmed = (ndon + 1) / 2
14718 ! write(unit=*,fmt=*) NMED, NDON
14719 !
14720 ! If the number of values is small, then use insertion sort
14721 !
14722 If (ndon < 35) Then
14723 !
14724 ! Bring minimum to first location to save test in decreasing loop
14725 !
14726 idcr = ndon
14727 If (xdont(1) < xdont(ndon)) Then
14728 xwrk = xdont(1)
14729 xwrkt(idcr) = xdont(idcr)
14730 Else
14731 xwrk = xdont(idcr)
14732 xwrkt(idcr) = xdont(1)
14733 end if
14734 Do iwrk = 1, ndon - 2
14735 idcr = idcr - 1
14736 xwrk1 = xdont(idcr)
14737 If (xwrk1 < xwrk) Then
14738 xwrkt(idcr) = xwrk
14739 xwrk = xwrk1
14740 Else
14741 xwrkt(idcr) = xwrk1
14742 end if
14743 End Do
14744 xwrkt(1) = xwrk
14745 !
14746 ! Sort the first half, until we have NMED sorted values
14747 !
14748 Do icrs = 3, nmed
14749 xwrk = xwrkt(icrs)
14750 idcr = icrs - 1
14751 Do
14752 If (xwrk >= xwrkt(idcr)) Exit
14753 xwrkt(idcr + 1) = xwrkt(idcr)
14754 idcr = idcr - 1
14755 End Do
14756 xwrkt(idcr + 1) = xwrk
14757 End Do
14758 !
14759 ! Insert any value less than the current median in the first half
14760 !
14761 Do icrs = nmed + 1, ndon
14762 xwrk = xwrkt(icrs)
14763 If (xwrk < xwrkt(nmed)) Then
14764 idcr = nmed - 1
14765 Do
14766 If (xwrk >= xwrkt(idcr)) Exit
14767 xwrkt(idcr + 1) = xwrkt(idcr)
14768 idcr = idcr - 1
14769 End Do
14770 xwrkt(idcr + 1) = xwrk
14771 End If
14772 End Do
14773 res_med = xwrkt(nmed)
14774 Return
14775 End If
14776 !
14777 ! Make sorted subsets of 7 elements
14778 ! This is done by a variant of insertion sort where a first
14779 ! pass is used to bring the smallest element to the first position
14780 ! decreasing disorder at the same time, so that we may remove
14781 ! remove the loop test in the insertion loop.
14782 !
14783 DO ideb = 1, ndon - 6, 7
14784 idcr = ideb + 6
14785 If (xdont(ideb) < xdont(idcr)) Then
14786 xwrk = xdont(ideb)
14787 xwrkt(idcr) = xdont(idcr)
14788 Else
14789 xwrk = xdont(idcr)
14790 xwrkt(idcr) = xdont(ideb)
14791 end if
14792 Do iwrk = 1, 5
14793 idcr = idcr - 1
14794 xwrk1 = xdont(idcr)
14795 If (xwrk1 < xwrk) Then
14796 xwrkt(idcr) = xwrk
14797 xwrk = xwrk1
14798 Else
14799 xwrkt(idcr) = xwrk1
14800 end if
14801 End Do
14802 xwrkt(ideb) = xwrk
14803 Do icrs = ideb + 2, ideb + 6
14804 xwrk = xwrkt(icrs)
14805 If (xwrk < xwrkt(icrs - 1)) Then
14806 xwrkt(icrs) = xwrkt(icrs - 1)
14807 idcr = icrs - 1
14808 xwrk1 = xwrkt(idcr - 1)
14809 Do
14810 If (xwrk >= xwrk1) Exit
14811 xwrkt(idcr) = xwrk1
14812 idcr = idcr - 1
14813 xwrk1 = xwrkt(idcr - 1)
14814 End Do
14815 xwrkt(idcr) = xwrk
14816 end if
14817 End Do
14818 End Do
14819 !
14820 ! Add-up alternatively + and - HUGE values to make the number of data
14821 ! an exact multiple of 7.
14822 !
14823 ideb = 7 * (ndon / 7)
14824 ntri = ndon
14825 If (ideb < ndon) Then
14826 !
14827 xwrk1 = xhuge
14828 Do icrs = ideb + 1, ideb + 7
14829 If (icrs <= ndon) Then
14830 xwrkt(icrs) = xdont(icrs)
14831 Else
14832 If (ne(xwrk1, xhuge)) nmed = nmed + 1
14833 xwrkt(icrs) = xwrk1
14834 xwrk1 = - xwrk1
14835 end if
14836 End Do
14837 !
14838 Do icrs = ideb + 2, ideb + 7
14839 xwrk = xwrkt(icrs)
14840 Do idcr = icrs - 1, ideb + 1, - 1
14841 If (xwrk >= xwrkt(idcr)) Exit
14842 xwrkt(idcr + 1) = xwrkt(idcr)
14843 End Do
14844 xwrkt(idcr + 1) = xwrk
14845 End Do
14846 !
14847 ntri = ideb + 7
14848 End If
14849 !
14850 ! Make the set of the indices of median values of each sorted subset
14851 !
14852 idon1 = 0
14853 Do idon = 1, ntri, 7
14854 idon1 = idon1 + 1
14855 imedt(idon1) = idon + 3
14856 End Do
14857 !
14858 ! Find XMED7, the median of the medians
14859 !
14860 xmed7 = r_valmed(xwrkt(imedt))
14861 !
14862 ! Count how many values are not higher than (and how many equal to) XMED7
14863 ! This number is at least 4 * 1/2 * (N/7) : 4 values in each of the
14864 ! subsets where the median is lower than the median of medians. For similar
14865 ! reasons, we also have at least 2N/7 values not lower than XMED7. At the
14866 ! same time, we find in each subset the index of the last value < XMED7,
14867 ! and that of the first > XMED7. These indices will be used to restrict the
14868 ! search for the median as the Kth element in the subset (> or <) where
14869 ! we know it to be.
14870 !
14871 idon1 = 1
14872 nleq = 0
14873 nequ = 0
14874 Do idon = 1, ntri, 7
14875 imed = idon + 3
14876 If (xwrkt(imed) > xmed7) Then
14877 imed = imed - 2
14878 If (xwrkt(imed) > xmed7) Then
14879 imed = imed - 1
14880 Else If (xwrkt(imed) < xmed7) Then
14881 imed = imed + 1
14882 end if
14883 Else If (xwrkt(imed) < xmed7) Then
14884 imed = imed + 2
14885 If (xwrkt(imed) > xmed7) Then
14886 imed = imed - 1
14887 Else If (xwrkt(imed) < xmed7) Then
14888 imed = imed + 1
14889 end if
14890 end if
14891 If (xwrkt(imed) > xmed7) Then
14892 nleq = nleq + imed - idon
14893 iendt(idon1) = imed - 1
14894 istrt(idon1) = imed
14895 Else If (xwrkt(imed) < xmed7) Then
14896 nleq = nleq + imed - idon + 1
14897 iendt(idon1) = imed
14898 istrt(idon1) = imed + 1
14899 Else ! If (XWRKT (IMED) == XMED7)
14900 nleq = nleq + imed - idon + 1
14901 nequ = nequ + 1
14902 iendt(idon1) = imed - 1
14903 Do imed1 = imed - 1, idon, -1
14904 If (eq(xwrkt(imed1), xmed7)) Then
14905 nequ = nequ + 1
14906 iendt(idon1) = imed1 - 1
14907 Else
14908 Exit
14909 End If
14910 End Do
14911 istrt(idon1) = imed + 1
14912 Do imed1 = imed + 1, idon + 6
14913 If (eq(xwrkt(imed1), xmed7)) Then
14914 nequ = nequ + 1
14915 nleq = nleq + 1
14916 istrt(idon1) = imed1 + 1
14917 Else
14918 Exit
14919 End If
14920 End Do
14921 end if
14922 idon1 = idon1 + 1
14923 End Do
14924 !
14925 ! Carry out a partial insertion sort to find the Kth smallest of the
14926 ! large values, or the Kth largest of the small values, according to
14927 ! what is needed.
14928 !
14929 If (nleq - nequ + 1 <= nmed) Then
14930 If (nleq < nmed) Then ! Not enough low values
14931 xwrk1 = xhuge
14932 nord = nmed - nleq
14933 idon1 = 0
14934 icrs1 = 1
14935 icrs2 = 0
14936 idcr = 0
14937 Do idon = 1, ntri, 7
14938 idon1 = idon1 + 1
14939 If (icrs2 < nord) Then
14940 Do icrs = istrt(idon1), idon + 6
14941 If (xwrkt(icrs) < xwrk1) Then
14942 xwrk = xwrkt(icrs)
14943 Do idcr = icrs1 - 1, 1, - 1
14944 If (xwrk >= xwrkt(idcr)) Exit
14945 xwrkt(idcr + 1) = xwrkt(idcr)
14946 End Do
14947 xwrkt(idcr + 1) = xwrk
14948 xwrk1 = xwrkt(icrs1)
14949 Else
14950 If (icrs2 < nord) Then
14951 xwrkt(icrs1) = xwrkt(icrs)
14952 xwrk1 = xwrkt(icrs1)
14953 end if
14954 End If
14955 icrs1 = min(nord, icrs1 + 1)
14956 icrs2 = min(nord, icrs2 + 1)
14957 End Do
14958 Else
14959 Do icrs = istrt(idon1), idon + 6
14960 If (xwrkt(icrs) >= xwrk1) Exit
14961 xwrk = xwrkt(icrs)
14962 Do idcr = icrs1 - 1, 1, - 1
14963 If (xwrk >= xwrkt(idcr)) Exit
14964 xwrkt(idcr + 1) = xwrkt(idcr)
14965 End Do
14966 xwrkt(idcr + 1) = xwrk
14967 xwrk1 = xwrkt(icrs1)
14968 End Do
14969 End If
14970 End Do
14971 res_med = xwrk1
14972 Return
14973 Else
14974 res_med = xmed7
14975 Return
14976 End If
14977 Else ! If (NLEQ > NMED)
14978 ! Not enough high values
14979 xwrk1 = -xhuge
14980 nord = nleq - nequ - nmed + 1
14981 idon1 = 0
14982 icrs1 = 1
14983 icrs2 = 0
14984 Do idon = 1, ntri, 7
14985 idon1 = idon1 + 1
14986 If (icrs2 < nord) Then
14987 !
14988 Do icrs = idon, iendt(idon1)
14989 If (xwrkt(icrs) > xwrk1) Then
14990 xwrk = xwrkt(icrs)
14991 idcr = icrs1 - 1
14992 Do idcr = icrs1 - 1, 1, - 1
14993 If (xwrk <= xwrkt(idcr)) Exit
14994 xwrkt(idcr + 1) = xwrkt(idcr)
14995 End Do
14996 xwrkt(idcr + 1) = xwrk
14997 xwrk1 = xwrkt(icrs1)
14998 Else
14999 If (icrs2 < nord) Then
15000 xwrkt(icrs1) = xwrkt(icrs)
15001 xwrk1 = xwrkt(icrs1)
15002 End If
15003 End If
15004 icrs1 = min(nord, icrs1 + 1)
15005 icrs2 = min(nord, icrs2 + 1)
15006 End Do
15007 Else
15008 Do icrs = iendt(idon1), idon, -1
15009 If (xwrkt(icrs) > xwrk1) Then
15010 xwrk = xwrkt(icrs)
15011 idcr = icrs1 - 1
15012 Do idcr = icrs1 - 1, 1, - 1
15013 If (xwrk <= xwrkt(idcr)) Exit
15014 xwrkt(idcr + 1) = xwrkt(idcr)
15015 End Do
15016 xwrkt(idcr + 1) = xwrk
15017 xwrk1 = xwrkt(icrs1)
15018 Else
15019 Exit
15020 End If
15021 End Do
15022 end if
15023 End Do
15024 !
15025 res_med = xwrk1
15026 Return
15027 End If
15028 !
15029 End Function r_valmed
15030
15031 Recursive Function i_valmed (XDONT) Result (res_med)
15032 ! Finds the median of XDONT using the recursive procedure
15033 ! described in Knuth, The Art of Computer Programming,
15034 ! vol. 3, 5.3.3 - This procedure is linear in time, and
15035 ! does not require to be able to interpolate in the
15036 ! set as the one used in INDNTH. It also has better worst
15037 ! case behavior than INDNTH, but is about 30% slower in
15038 ! average for random uniformly distributed values.
15039 ! __________________________________________________________
15040 ! __________________________________________________________
15041 Integer(kind = i4), Dimension (:), Intent (In) :: XDONT
15042 Integer(kind = i4) :: res_med
15043 ! __________________________________________________________
15044 Integer(kind = i4), Parameter :: XHUGE = huge (xdont)
15045 Integer(kind = i4), Dimension (SIZE(XDONT) + 6) :: XWRKT
15046 Integer(kind = i4) :: XWRK, XWRK1, XMED7
15047 !
15048 Integer(kind = i4), Dimension ((SIZE(XDONT) + 6) / 7) :: ISTRT, IENDT, IMEDT
15049 Integer(kind = i4) :: NDON, NTRI, NMED, NORD, NEQU, NLEQ, IMED, IDON, IDON1
15050 Integer(kind = i4) :: IDEB, IWRK, IDCR, ICRS, ICRS1, ICRS2, IMED1
15051 !
15052 ndon = SIZE (xdont)
15053 nmed = (ndon + 1) / 2
15054 ! write(unit=*,fmt=*) NMED, NDON
15055 !
15056 ! If the number of values is small, then use insertion sort
15057 !
15058 If (ndon < 35) Then
15059 !
15060 ! Bring minimum to first location to save test in decreasing loop
15061 !
15062 idcr = ndon
15063 If (xdont(1) < xdont(ndon)) Then
15064 xwrk = xdont(1)
15065 xwrkt(idcr) = xdont(idcr)
15066 Else
15067 xwrk = xdont(idcr)
15068 xwrkt(idcr) = xdont(1)
15069 end if
15070 Do iwrk = 1, ndon - 2
15071 idcr = idcr - 1
15072 xwrk1 = xdont(idcr)
15073 If (xwrk1 < xwrk) Then
15074 xwrkt(idcr) = xwrk
15075 xwrk = xwrk1
15076 Else
15077 xwrkt(idcr) = xwrk1
15078 end if
15079 End Do
15080 xwrkt(1) = xwrk
15081 !
15082 ! Sort the first half, until we have NMED sorted values
15083 !
15084 Do icrs = 3, nmed
15085 xwrk = xwrkt(icrs)
15086 idcr = icrs - 1
15087 Do
15088 If (xwrk >= xwrkt(idcr)) Exit
15089 xwrkt(idcr + 1) = xwrkt(idcr)
15090 idcr = idcr - 1
15091 End Do
15092 xwrkt(idcr + 1) = xwrk
15093 End Do
15094 !
15095 ! Insert any value less than the current median in the first half
15096 !
15097 Do icrs = nmed + 1, ndon
15098 xwrk = xwrkt(icrs)
15099 If (xwrk < xwrkt(nmed)) Then
15100 idcr = nmed - 1
15101 Do
15102 If (xwrk >= xwrkt(idcr)) Exit
15103 xwrkt(idcr + 1) = xwrkt(idcr)
15104 idcr = idcr - 1
15105 End Do
15106 xwrkt(idcr + 1) = xwrk
15107 End If
15108 End Do
15109 res_med = xwrkt(nmed)
15110 Return
15111 End If
15112 !
15113 ! Make sorted subsets of 7 elements
15114 ! This is done by a variant of insertion sort where a first
15115 ! pass is used to bring the smallest element to the first position
15116 ! decreasing disorder at the same time, so that we may remove
15117 ! remove the loop test in the insertion loop.
15118 !
15119 DO ideb = 1, ndon - 6, 7
15120 idcr = ideb + 6
15121 If (xdont(ideb) < xdont(idcr)) Then
15122 xwrk = xdont(ideb)
15123 xwrkt(idcr) = xdont(idcr)
15124 Else
15125 xwrk = xdont(idcr)
15126 xwrkt(idcr) = xdont(ideb)
15127 end if
15128 Do iwrk = 1, 5
15129 idcr = idcr - 1
15130 xwrk1 = xdont(idcr)
15131 If (xwrk1 < xwrk) Then
15132 xwrkt(idcr) = xwrk
15133 xwrk = xwrk1
15134 Else
15135 xwrkt(idcr) = xwrk1
15136 end if
15137 End Do
15138 xwrkt(ideb) = xwrk
15139 Do icrs = ideb + 2, ideb + 6
15140 xwrk = xwrkt(icrs)
15141 If (xwrk < xwrkt(icrs - 1)) Then
15142 xwrkt(icrs) = xwrkt(icrs - 1)
15143 idcr = icrs - 1
15144 xwrk1 = xwrkt(idcr - 1)
15145 Do
15146 If (xwrk >= xwrk1) Exit
15147 xwrkt(idcr) = xwrk1
15148 idcr = idcr - 1
15149 xwrk1 = xwrkt(idcr - 1)
15150 End Do
15151 xwrkt(idcr) = xwrk
15152 end if
15153 End Do
15154 End Do
15155 !
15156 ! Add-up alternatively + and - HUGE values to make the number of data
15157 ! an exact multiple of 7.
15158 !
15159 ideb = 7 * (ndon / 7)
15160 ntri = ndon
15161 If (ideb < ndon) Then
15162 !
15163 xwrk1 = xhuge
15164 Do icrs = ideb + 1, ideb + 7
15165 If (icrs <= ndon) Then
15166 xwrkt(icrs) = xdont(icrs)
15167 Else
15168 If (xwrk1 /= xhuge) nmed = nmed + 1
15169 xwrkt(icrs) = xwrk1
15170 xwrk1 = - xwrk1
15171 end if
15172 End Do
15173 !
15174 Do icrs = ideb + 2, ideb + 7
15175 xwrk = xwrkt(icrs)
15176 Do idcr = icrs - 1, ideb + 1, - 1
15177 If (xwrk >= xwrkt(idcr)) Exit
15178 xwrkt(idcr + 1) = xwrkt(idcr)
15179 End Do
15180 xwrkt(idcr + 1) = xwrk
15181 End Do
15182 !
15183 ntri = ideb + 7
15184 End If
15185 !
15186 ! Make the set of the indices of median values of each sorted subset
15187 !
15188 idon1 = 0
15189 Do idon = 1, ntri, 7
15190 idon1 = idon1 + 1
15191 imedt(idon1) = idon + 3
15192 End Do
15193 !
15194 ! Find XMED7, the median of the medians
15195 !
15196 xmed7 = i_valmed(xwrkt(imedt))
15197 !
15198 ! Count how many values are not higher than (and how many equal to) XMED7
15199 ! This number is at least 4 * 1/2 * (N/7) : 4 values in each of the
15200 ! subsets where the median is lower than the median of medians. For similar
15201 ! reasons, we also have at least 2N/7 values not lower than XMED7. At the
15202 ! same time, we find in each subset the index of the last value < XMED7,
15203 ! and that of the first > XMED7. These indices will be used to restrict the
15204 ! search for the median as the Kth element in the subset (> or <) where
15205 ! we know it to be.
15206 !
15207 idon1 = 1
15208 nleq = 0
15209 nequ = 0
15210 Do idon = 1, ntri, 7
15211 imed = idon + 3
15212 If (xwrkt(imed) > xmed7) Then
15213 imed = imed - 2
15214 If (xwrkt(imed) > xmed7) Then
15215 imed = imed - 1
15216 Else If (xwrkt(imed) < xmed7) Then
15217 imed = imed + 1
15218 end if
15219 Else If (xwrkt(imed) < xmed7) Then
15220 imed = imed + 2
15221 If (xwrkt(imed) > xmed7) Then
15222 imed = imed - 1
15223 Else If (xwrkt(imed) < xmed7) Then
15224 imed = imed + 1
15225 end if
15226 end if
15227 If (xwrkt(imed) > xmed7) Then
15228 nleq = nleq + imed - idon
15229 iendt(idon1) = imed - 1
15230 istrt(idon1) = imed
15231 Else If (xwrkt(imed) < xmed7) Then
15232 nleq = nleq + imed - idon + 1
15233 iendt(idon1) = imed
15234 istrt(idon1) = imed + 1
15235 Else ! If (XWRKT (IMED) == XMED7)
15236 nleq = nleq + imed - idon + 1
15237 nequ = nequ + 1
15238 iendt(idon1) = imed - 1
15239 Do imed1 = imed - 1, idon, -1
15240 If (xwrkt(imed1) == xmed7) Then
15241 nequ = nequ + 1
15242 iendt(idon1) = imed1 - 1
15243 Else
15244 Exit
15245 End If
15246 End Do
15247 istrt(idon1) = imed + 1
15248 Do imed1 = imed + 1, idon + 6
15249 If (xwrkt(imed1) == xmed7) Then
15250 nequ = nequ + 1
15251 nleq = nleq + 1
15252 istrt(idon1) = imed1 + 1
15253 Else
15254 Exit
15255 End If
15256 End Do
15257 end if
15258 idon1 = idon1 + 1
15259 End Do
15260 !
15261 ! Carry out a partial insertion sort to find the Kth smallest of the
15262 ! large values, or the Kth largest of the small values, according to
15263 ! what is needed.
15264 !
15265 If (nleq - nequ + 1 <= nmed) Then
15266 If (nleq < nmed) Then ! Not enough low values
15267 xwrk1 = xhuge
15268 nord = nmed - nleq
15269 idon1 = 0
15270 icrs1 = 1
15271 icrs2 = 0
15272 idcr = 0
15273 Do idon = 1, ntri, 7
15274 idon1 = idon1 + 1
15275 If (icrs2 < nord) Then
15276 Do icrs = istrt(idon1), idon + 6
15277 If (xwrkt(icrs) < xwrk1) Then
15278 xwrk = xwrkt(icrs)
15279 Do idcr = icrs1 - 1, 1, - 1
15280 If (xwrk >= xwrkt(idcr)) Exit
15281 xwrkt(idcr + 1) = xwrkt(idcr)
15282 End Do
15283 xwrkt(idcr + 1) = xwrk
15284 xwrk1 = xwrkt(icrs1)
15285 Else
15286 If (icrs2 < nord) Then
15287 xwrkt(icrs1) = xwrkt(icrs)
15288 xwrk1 = xwrkt(icrs1)
15289 end if
15290 End If
15291 icrs1 = min(nord, icrs1 + 1)
15292 icrs2 = min(nord, icrs2 + 1)
15293 End Do
15294 Else
15295 Do icrs = istrt(idon1), idon + 6
15296 If (xwrkt(icrs) >= xwrk1) Exit
15297 xwrk = xwrkt(icrs)
15298 Do idcr = icrs1 - 1, 1, - 1
15299 If (xwrk >= xwrkt(idcr)) Exit
15300 xwrkt(idcr + 1) = xwrkt(idcr)
15301 End Do
15302 xwrkt(idcr + 1) = xwrk
15303 xwrk1 = xwrkt(icrs1)
15304 End Do
15305 End If
15306 End Do
15307 res_med = xwrk1
15308 Return
15309 Else
15310 res_med = xmed7
15311 Return
15312 End If
15313 Else ! If (NLEQ > NMED)
15314 ! Not enough high values
15315 xwrk1 = -xhuge
15316 nord = nleq - nequ - nmed + 1
15317 idon1 = 0
15318 icrs1 = 1
15319 icrs2 = 0
15320 Do idon = 1, ntri, 7
15321 idon1 = idon1 + 1
15322 If (icrs2 < nord) Then
15323 !
15324 Do icrs = idon, iendt(idon1)
15325 If (xwrkt(icrs) > xwrk1) Then
15326 xwrk = xwrkt(icrs)
15327 idcr = icrs1 - 1
15328 Do idcr = icrs1 - 1, 1, - 1
15329 If (xwrk <= xwrkt(idcr)) Exit
15330 xwrkt(idcr + 1) = xwrkt(idcr)
15331 End Do
15332 xwrkt(idcr + 1) = xwrk
15333 xwrk1 = xwrkt(icrs1)
15334 Else
15335 If (icrs2 < nord) Then
15336 xwrkt(icrs1) = xwrkt(icrs)
15337 xwrk1 = xwrkt(icrs1)
15338 End If
15339 End If
15340 icrs1 = min(nord, icrs1 + 1)
15341 icrs2 = min(nord, icrs2 + 1)
15342 End Do
15343 Else
15344 Do icrs = iendt(idon1), idon, -1
15345 If (xwrkt(icrs) > xwrk1) Then
15346 xwrk = xwrkt(icrs)
15347 idcr = icrs1 - 1
15348 Do idcr = icrs1 - 1, 1, - 1
15349 If (xwrk <= xwrkt(idcr)) Exit
15350 xwrkt(idcr + 1) = xwrkt(idcr)
15351 End Do
15352 xwrkt(idcr + 1) = xwrk
15353 xwrk1 = xwrkt(icrs1)
15354 Else
15355 Exit
15356 End If
15357 End Do
15358 end if
15359 End Do
15360 !
15361 res_med = xwrk1
15362 Return
15363 End If
15364 !
15365 End Function i_valmed
15366
15367 Function d_valnth (XDONT, NORD) Result (valnth)
15368 ! Return NORDth value of XDONT, i.e fractile of order NORD/SIZE(XDONT).
15369 ! __________________________________________________________
15370 ! This routine uses a pivoting strategy such as the one of
15371 ! finding the median based on the quicksort algorithm, but
15372 ! we skew the pivot choice to try to bring it to NORD as
15373 ! fast as possible. It uses 2 temporary arrays, where it
15374 ! stores the indices of the values smaller than the pivot
15375 ! (ILOWT), and the indices of values larger than the pivot
15376 ! that we might still need later on (IHIGT). It iterates
15377 ! until it can bring the number of values in ILOWT to
15378 ! exactly NORD, and then finds the maximum of this set.
15379 ! Michel Olagnon - Aug. 2000
15380 ! __________________________________________________________
15381 ! __________________________________________________________
15382 real(Kind = dp), Dimension (:), Intent (In) :: xdont
15383 real(Kind = dp) :: valnth
15384 Integer(kind = i4), Intent (In) :: NORD
15385 ! __________________________________________________________
15386 real(Kind = dp), Dimension (SIZE(XDONT)) :: xlowt, xhigt
15387 real(Kind = dp) :: xpiv, xwrk, xwrk1, xwrk2, xwrk3, xmin, xmax
15388 !
15389 Integer(kind = i4) :: NDON, JHIG, JLOW, IHIG
15390 Integer(kind = i4) :: IMIL, IFIN, ICRS, IDCR, ILOW
15391 Integer(kind = i4) :: JLM2, JLM1, JHM2, JHM1, INTH
15392 !
15393 ndon = SIZE (xdont)
15394 inth = max(min(nord, ndon), 1)
15395 !
15396 ! First loop is used to fill-in XLOWT, XHIGT at the same time
15397 !
15398 If (ndon < 2) Then
15399 If (inth == 1) valnth = xdont(1)
15400 Return
15401 End If
15402 !
15403 ! One chooses a pivot, best estimate possible to put fractile near
15404 ! mid-point of the set of low values.
15405 !
15406 If (xdont(2) < xdont(1)) Then
15407 xlowt(1) = xdont(2)
15408 xhigt(1) = xdont(1)
15409 Else
15410 xlowt(1) = xdont(1)
15411 xhigt(1) = xdont(2)
15412 End If
15413 !
15414 If (ndon < 3) Then
15415 If (inth == 1) valnth = xlowt(1)
15416 If (inth == 2) valnth = xhigt(1)
15417 Return
15418 End If
15419 !
15420 If (xdont(3) < xhigt(1)) Then
15421 xhigt(2) = xhigt(1)
15422 If (xdont(3) < xlowt(1)) Then
15423 xhigt(1) = xlowt(1)
15424 xlowt(1) = xdont(3)
15425 Else
15426 xhigt(1) = xdont(3)
15427 End If
15428 Else
15429 xhigt(2) = xdont(3)
15430 End If
15431 !
15432 If (ndon < 4) Then
15433 If (inth == 1) Then
15434 valnth = xlowt(1)
15435 Else
15436 valnth = xhigt(inth - 1)
15437 End If
15438 Return
15439 End If
15440 !
15441 If (xdont(ndon) < xhigt(1)) Then
15442 xhigt(3) = xhigt(2)
15443 xhigt(2) = xhigt(1)
15444 If (xdont(ndon) < xlowt(1)) Then
15445 xhigt(1) = xlowt(1)
15446 xlowt(1) = xdont(ndon)
15447 Else
15448 xhigt(1) = xdont(ndon)
15449 End If
15450 Else
15451 xhigt(3) = xdont(ndon)
15452 End If
15453 !
15454 If (ndon < 5) Then
15455 If (inth == 1) Then
15456 valnth = xlowt(1)
15457 Else
15458 valnth = xhigt(inth - 1)
15459 End If
15460 Return
15461 End If
15462 !
15463
15464 jlow = 1
15465 jhig = 3
15466 xpiv = xlowt(1) + real(2 * inth, dp) / real(ndon + inth, dp) * (xhigt(3) - xlowt(1))
15467 If (xpiv >= xhigt(1)) Then
15468 xpiv = xlowt(1) + real(2 * inth, dp) / real(ndon + inth, dp) * &
15469 (xhigt(2) - xlowt(1))
15470 If (xpiv >= xhigt(1)) &
15471 xpiv = xlowt(1) + real(2 * inth, dp) / real(ndon + inth, dp) * &
15472 (xhigt(1) - xlowt(1))
15473 End If
15474 !
15475 ! One puts values > pivot in the end and those <= pivot
15476 ! at the beginning. This is split in 2 cases, so that
15477 ! we can skip the loop test a number of times.
15478 ! As we are also filling in the work arrays at the same time
15479 ! we stop filling in the XHIGT array as soon as we have more
15480 ! than enough values in XLOWT.
15481 !
15482 !
15483 If (xdont(ndon) > xpiv) Then
15484 icrs = 3
15485 Do
15486 icrs = icrs + 1
15487 If (xdont(icrs) > xpiv) Then
15488 If (icrs >= ndon) Exit
15489 jhig = jhig + 1
15490 xhigt(jhig) = xdont(icrs)
15491 Else
15492 jlow = jlow + 1
15493 xlowt(jlow) = xdont(icrs)
15494 If (jlow >= inth) Exit
15495 End If
15496 End Do
15497 !
15498 ! One restricts further processing because it is no use
15499 ! to store more high values
15500 !
15501 If (icrs < ndon - 1) Then
15502 Do
15503 icrs = icrs + 1
15504 If (xdont(icrs) <= xpiv) Then
15505 jlow = jlow + 1
15506 xlowt(jlow) = xdont(icrs)
15507 Else If (icrs >= ndon) Then
15508 Exit
15509 End If
15510 End Do
15511 End If
15512 !
15513 !
15514 Else
15515 !
15516 ! Same as above, but this is not as easy to optimize, so the
15517 ! DO-loop is kept
15518 !
15519 Do icrs = 4, ndon - 1
15520 If (xdont(icrs) > xpiv) Then
15521 jhig = jhig + 1
15522 xhigt(jhig) = xdont(icrs)
15523 Else
15524 jlow = jlow + 1
15525 xlowt(jlow) = xdont(icrs)
15526 If (jlow >= inth) Exit
15527 End If
15528 End Do
15529 !
15530 If (icrs < ndon - 1) Then
15531 Do
15532 icrs = icrs + 1
15533 If (xdont(icrs) <= xpiv) Then
15534 If (icrs >= ndon) Exit
15535 jlow = jlow + 1
15536 xlowt(jlow) = xdont(icrs)
15537 End If
15538 End Do
15539 End If
15540 End If
15541 !
15542 jlm2 = 0
15543 jlm1 = 0
15544 jhm2 = 0
15545 jhm1 = 0
15546 Do
15547 If (jlm2 == jlow .And. jhm2 == jhig) Then
15548 !
15549 ! We are oscillating. Perturbate by bringing JLOW closer by one
15550 ! to INTH
15551 !
15552 If (inth > jlow) Then
15553 xmin = xhigt(1)
15554 ihig = 1
15555 Do icrs = 2, jhig
15556 If (xhigt(icrs) < xmin) Then
15557 xmin = xhigt(icrs)
15558 ihig = icrs
15559 End If
15560 End Do
15561 !
15562 jlow = jlow + 1
15563 xlowt(jlow) = xhigt(ihig)
15564 xhigt(ihig) = xhigt(jhig)
15565 jhig = jhig - 1
15566 Else
15567
15568 xmax = xlowt(jlow)
15569 jlow = jlow - 1
15570 Do icrs = 1, jlow
15571 If (xlowt(icrs) > xmax) Then
15572 xwrk = xmax
15573 xmax = xlowt(icrs)
15574 xlowt(icrs) = xwrk
15575 End If
15576 End Do
15577 End If
15578 End If
15579 jlm2 = jlm1
15580 jlm1 = jlow
15581 jhm2 = jhm1
15582 jhm1 = jhig
15583 !
15584 ! We try to bring the number of values in the low values set
15585 ! closer to INTH.
15586 !
15587 Select Case (inth - jlow)
15588 Case (2 :)
15589 !
15590 ! Not enough values in low part, at least 2 are missing
15591 !
15592 inth = inth - jlow
15593 jlow = 0
15594 Select Case (jhig)
15595 !!!!! CASE DEFAULT
15596 !!!!! write (unit=*,fmt=*) "Assertion failed"
15597 !!!!! STOP
15598 !
15599 ! We make a special case when we have so few values in
15600 ! the high values set that it is bad performance to choose a pivot
15601 ! and apply the general algorithm.
15602 !
15603 Case (2)
15604 If (xhigt(1) <= xhigt(2)) Then
15605 jlow = jlow + 1
15606 xlowt(jlow) = xhigt(1)
15607 jlow = jlow + 1
15608 xlowt(jlow) = xhigt(2)
15609 Else
15610 jlow = jlow + 1
15611 xlowt(jlow) = xhigt(2)
15612 jlow = jlow + 1
15613 xlowt(jlow) = xhigt(1)
15614 End If
15615 Exit
15616 !
15617 Case (3)
15618 !
15619 !
15620 xwrk1 = xhigt(1)
15621 xwrk2 = xhigt(2)
15622 xwrk3 = xhigt(3)
15623 If (xwrk2 < xwrk1) Then
15624 xhigt(1) = xwrk2
15625 xhigt(2) = xwrk1
15626 xwrk2 = xwrk1
15627 End If
15628 If (xwrk2 > xwrk3) Then
15629 xhigt(3) = xwrk2
15630 xhigt(2) = xwrk3
15631 xwrk2 = xwrk3
15632 If (xwrk2 < xhigt(1)) Then
15633 xhigt(2) = xhigt(1)
15634 xhigt(1) = xwrk2
15635 End If
15636 End If
15637 jhig = 0
15638 Do icrs = jlow + 1, inth
15639 jhig = jhig + 1
15640 xlowt(icrs) = xhigt(jhig)
15641 End Do
15642 jlow = inth
15643 Exit
15644 !
15645 Case (4 :)
15646 !
15647 !
15648 ifin = jhig
15649 !
15650 ! One chooses a pivot from the 2 first values and the last one.
15651 ! This should ensure sufficient renewal between iterations to
15652 ! avoid worst case behavior effects.
15653 !
15654 xwrk1 = xhigt(1)
15655 xwrk2 = xhigt(2)
15656 xwrk3 = xhigt(ifin)
15657 If (xwrk2 < xwrk1) Then
15658 xhigt(1) = xwrk2
15659 xhigt(2) = xwrk1
15660 xwrk2 = xwrk1
15661 End If
15662 If (xwrk2 > xwrk3) Then
15663 xhigt(ifin) = xwrk2
15664 xhigt(2) = xwrk3
15665 xwrk2 = xwrk3
15666 If (xwrk2 < xhigt(1)) Then
15667 xhigt(2) = xhigt(1)
15668 xhigt(1) = xwrk2
15669 End If
15670 End If
15671 !
15672 xwrk1 = xhigt(1)
15673 jlow = jlow + 1
15674 xlowt(jlow) = xwrk1
15675 xpiv = xwrk1 + 0.5 * (xhigt(ifin) - xwrk1)
15676 !
15677 ! One takes values <= pivot to XLOWT
15678 ! Again, 2 parts, one where we take care of the remaining
15679 ! high values because we might still need them, and the
15680 ! other when we know that we will have more than enough
15681 ! low values in the end.
15682 !
15683 jhig = 0
15684 Do icrs = 2, ifin
15685 If (xhigt(icrs) <= xpiv) Then
15686 jlow = jlow + 1
15687 xlowt(jlow) = xhigt(icrs)
15688 If (jlow >= inth) Exit
15689 Else
15690 jhig = jhig + 1
15691 xhigt(jhig) = xhigt(icrs)
15692 End If
15693 End Do
15694 !
15695 Do icrs = icrs + 1, ifin
15696 If (xhigt(icrs) <= xpiv) Then
15697 jlow = jlow + 1
15698 xlowt(jlow) = xhigt(icrs)
15699 End If
15700 End Do
15701 End Select
15702 !
15703 !
15704 Case (1)
15705 !
15706 ! Only 1 value is missing in low part
15707 !
15708 xmin = xhigt(1)
15709 ihig = 1
15710 Do icrs = 2, jhig
15711 If (xhigt(icrs) < xmin) Then
15712 xmin = xhigt(icrs)
15713 ihig = icrs
15714 End If
15715 End Do
15716 !
15717 valnth = xhigt(ihig)
15718 Return
15719 !
15720 !
15721 Case (0)
15722 !
15723 ! Low part is exactly what we want
15724 !
15725 Exit
15726 !
15727 !
15728 Case (-5 : -1)
15729 !
15730 ! Only few values too many in low part
15731 !
15732 xhigt(1) = xlowt(1)
15733 ilow = 1 + inth - jlow
15734 Do icrs = 2, inth
15735 xwrk = xlowt(icrs)
15736 Do idcr = icrs - 1, max(1, ilow), - 1
15737 If (xwrk < xhigt(idcr)) Then
15738 xhigt(idcr + 1) = xhigt(idcr)
15739 Else
15740 Exit
15741 End If
15742 End Do
15743 xhigt(idcr + 1) = xwrk
15744 ilow = ilow + 1
15745 End Do
15746 !
15747 xwrk1 = xhigt(inth)
15748 ilow = 2 * inth - jlow
15749 Do icrs = inth + 1, jlow
15750 If (xlowt(icrs) < xwrk1) Then
15751 xwrk = xlowt(icrs)
15752 Do idcr = inth - 1, max(1, ilow), - 1
15753 If (xwrk >= xhigt(idcr)) Exit
15754 xhigt(idcr + 1) = xhigt(idcr)
15755 End Do
15756 xhigt(idcr + 1) = xlowt(icrs)
15757 xwrk1 = xhigt(inth)
15758 End If
15759 ilow = ilow + 1
15760 End Do
15761 !
15762 valnth = xhigt(inth)
15763 Return
15764 !
15765 !
15766 Case (: -6)
15767 !
15768 ! last case: too many values in low part
15769 !
15770
15771 imil = (jlow + 1) / 2
15772 ifin = jlow
15773 !
15774 ! One chooses a pivot from 1st, last, and middle values
15775 !
15776 If (xlowt(imil) < xlowt(1)) Then
15777 xwrk = xlowt(1)
15778 xlowt(1) = xlowt(imil)
15779 xlowt(imil) = xwrk
15780 End If
15781 If (xlowt(imil) > xlowt(ifin)) Then
15782 xwrk = xlowt(ifin)
15783 xlowt(ifin) = xlowt(imil)
15784 xlowt(imil) = xwrk
15785 If (xlowt(imil) < xlowt(1)) Then
15786 xwrk = xlowt(1)
15787 xlowt(1) = xlowt(imil)
15788 xlowt(imil) = xwrk
15789 End If
15790 End If
15791 If (ifin <= 3) Exit
15792 !
15793 xpiv = xlowt(1) + real(inth, dp) / real(jlow + inth, dp) * &
15794 (xlowt(ifin) - xlowt(1))
15795
15796 !
15797 ! One takes values > XPIV to XHIGT
15798 !
15799 jhig = 0
15800 jlow = 0
15801 !
15802 If (xlowt(ifin) > xpiv) Then
15803 icrs = 0
15804 Do
15805 icrs = icrs + 1
15806 If (xlowt(icrs) > xpiv) Then
15807 jhig = jhig + 1
15808 xhigt(jhig) = xlowt(icrs)
15809 If (icrs >= ifin) Exit
15810 Else
15811 jlow = jlow + 1
15812 xlowt(jlow) = xlowt(icrs)
15813 If (jlow >= inth) Exit
15814 End If
15815 End Do
15816 !
15817 If (icrs < ifin) Then
15818 Do
15819 icrs = icrs + 1
15820 If (xlowt(icrs) <= xpiv) Then
15821 jlow = jlow + 1
15822 xlowt(jlow) = xlowt(icrs)
15823 Else
15824 If (icrs >= ifin) Exit
15825 End If
15826 End Do
15827 End If
15828 Else
15829 Do icrs = 1, ifin
15830 If (xlowt(icrs) > xpiv) Then
15831 jhig = jhig + 1
15832 xhigt(jhig) = xlowt(icrs)
15833 Else
15834 jlow = jlow + 1
15835 xlowt(jlow) = xlowt(icrs)
15836 If (jlow >= inth) Exit
15837 End If
15838 End Do
15839 !
15840 Do icrs = icrs + 1, ifin
15841 If (xlowt(icrs) <= xpiv) Then
15842 jlow = jlow + 1
15843 xlowt(jlow) = xlowt(icrs)
15844 End If
15845 End Do
15846 End If
15847 !
15848 End Select
15849 !
15850 End Do
15851 !
15852 ! Now, we only need to find maximum of the 1:INTH set
15853 !
15854 valnth = maxval(xlowt(1 : inth))
15855 Return
15856 !
15857 !
15858 End Function d_valnth
15859
15860 Function r_valnth (XDONT, NORD) Result (valnth)
15861 ! Return NORDth value of XDONT, i.e fractile of order NORD/SIZE(XDONT).
15862 ! __________________________________________________________
15863 ! This routine uses a pivoting strategy such as the one of
15864 ! finding the median based on the quicksort algorithm, but
15865 ! we skew the pivot choice to try to bring it to NORD as
15866 ! fast as possible. It uses 2 temporary arrays, where it
15867 ! stores the indices of the values smaller than the pivot
15868 ! (ILOWT), and the indices of values larger than the pivot
15869 ! that we might still need later on (IHIGT). It iterates
15870 ! until it can bring the number of values in ILOWT to
15871 ! exactly NORD, and then finds the maximum of this set.
15872 ! Michel Olagnon - Aug. 2000
15873 ! __________________________________________________________
15874 ! _________________________________________________________
15875 Real(kind = sp), Dimension (:), Intent (In) :: xdont
15876 Real(kind = sp) :: valnth
15877 Integer(kind = i4), Intent (In) :: NORD
15878 ! __________________________________________________________
15879 Real(kind = sp), Dimension (SIZE(XDONT)) :: xlowt, xhigt
15880 Real(kind = sp) :: xpiv, xwrk, xwrk1, xwrk2, xwrk3, xmin, xmax
15881 !
15882 Integer(kind = i4) :: NDON, JHIG, JLOW, IHIG
15883 Integer(kind = i4) :: IMIL, IFIN, ICRS, IDCR, ILOW
15884 Integer(kind = i4) :: JLM2, JLM1, JHM2, JHM1, INTH
15885 !
15886 ndon = SIZE (xdont)
15887 inth = max(min(nord, ndon), 1)
15888 !
15889 ! First loop is used to fill-in XLOWT, XHIGT at the same time
15890 !
15891 If (ndon < 2) Then
15892 If (inth == 1) valnth = xdont(1)
15893 Return
15894 End If
15895 !
15896 ! One chooses a pivot, best estimate possible to put fractile near
15897 ! mid-point of the set of low values.
15898 !
15899 If (xdont(2) < xdont(1)) Then
15900 xlowt(1) = xdont(2)
15901 xhigt(1) = xdont(1)
15902 Else
15903 xlowt(1) = xdont(1)
15904 xhigt(1) = xdont(2)
15905 End If
15906 !
15907 If (ndon < 3) Then
15908 If (inth == 1) valnth = xlowt(1)
15909 If (inth == 2) valnth = xhigt(1)
15910 Return
15911 End If
15912 !
15913 If (xdont(3) < xhigt(1)) Then
15914 xhigt(2) = xhigt(1)
15915 If (xdont(3) < xlowt(1)) Then
15916 xhigt(1) = xlowt(1)
15917 xlowt(1) = xdont(3)
15918 Else
15919 xhigt(1) = xdont(3)
15920 End If
15921 Else
15922 xhigt(2) = xdont(3)
15923 End If
15924 !
15925 If (ndon < 4) Then
15926 If (inth == 1) Then
15927 valnth = xlowt(1)
15928 Else
15929 valnth = xhigt(inth - 1)
15930 End If
15931 Return
15932 End If
15933 !
15934 If (xdont(ndon) < xhigt(1)) Then
15935 xhigt(3) = xhigt(2)
15936 xhigt(2) = xhigt(1)
15937 If (xdont(ndon) < xlowt(1)) Then
15938 xhigt(1) = xlowt(1)
15939 xlowt(1) = xdont(ndon)
15940 Else
15941 xhigt(1) = xdont(ndon)
15942 End If
15943 Else
15944 xhigt(3) = xdont(ndon)
15945 End If
15946 !
15947 If (ndon < 5) Then
15948 If (inth == 1) Then
15949 valnth = xlowt(1)
15950 Else
15951 valnth = xhigt(inth - 1)
15952 End If
15953 Return
15954 End If
15955 !
15956
15957 jlow = 1
15958 jhig = 3
15959 xpiv = xlowt(1) + real(2 * inth, sp) / real(ndon + inth, sp) * (xhigt(3) - xlowt(1))
15960 If (xpiv >= xhigt(1)) Then
15961 xpiv = xlowt(1) + real(2 * inth, sp) / real(ndon + inth, sp) * &
15962 (xhigt(2) - xlowt(1))
15963 If (xpiv >= xhigt(1)) &
15964 xpiv = xlowt(1) + real(2 * inth, sp) / real(ndon + inth, sp) * &
15965 (xhigt(1) - xlowt(1))
15966 End If
15967 !
15968 ! One puts values > pivot in the end and those <= pivot
15969 ! at the beginning. This is split in 2 cases, so that
15970 ! we can skip the loop test a number of times.
15971 ! As we are also filling in the work arrays at the same time
15972 ! we stop filling in the XHIGT array as soon as we have more
15973 ! than enough values in XLOWT.
15974 !
15975 !
15976 If (xdont(ndon) > xpiv) Then
15977 icrs = 3
15978 Do
15979 icrs = icrs + 1
15980 If (xdont(icrs) > xpiv) Then
15981 If (icrs >= ndon) Exit
15982 jhig = jhig + 1
15983 xhigt(jhig) = xdont(icrs)
15984 Else
15985 jlow = jlow + 1
15986 xlowt(jlow) = xdont(icrs)
15987 If (jlow >= inth) Exit
15988 End If
15989 End Do
15990 !
15991 ! One restricts further processing because it is no use
15992 ! to store more high values
15993 !
15994 If (icrs < ndon - 1) Then
15995 Do
15996 icrs = icrs + 1
15997 If (xdont(icrs) <= xpiv) Then
15998 jlow = jlow + 1
15999 xlowt(jlow) = xdont(icrs)
16000 Else If (icrs >= ndon) Then
16001 Exit
16002 End If
16003 End Do
16004 End If
16005 !
16006 !
16007 Else
16008 !
16009 ! Same as above, but this is not as easy to optimize, so the
16010 ! DO-loop is kept
16011 !
16012 Do icrs = 4, ndon - 1
16013 If (xdont(icrs) > xpiv) Then
16014 jhig = jhig + 1
16015 xhigt(jhig) = xdont(icrs)
16016 Else
16017 jlow = jlow + 1
16018 xlowt(jlow) = xdont(icrs)
16019 If (jlow >= inth) Exit
16020 End If
16021 End Do
16022 !
16023 If (icrs < ndon - 1) Then
16024 Do
16025 icrs = icrs + 1
16026 If (xdont(icrs) <= xpiv) Then
16027 If (icrs >= ndon) Exit
16028 jlow = jlow + 1
16029 xlowt(jlow) = xdont(icrs)
16030 End If
16031 End Do
16032 End If
16033 End If
16034 !
16035 jlm2 = 0
16036 jlm1 = 0
16037 jhm2 = 0
16038 jhm1 = 0
16039 Do
16040 If (jlm2 == jlow .And. jhm2 == jhig) Then
16041 !
16042 ! We are oscillating. Perturbate by bringing JLOW closer by one
16043 ! to INTH
16044 !
16045 If (inth > jlow) Then
16046 xmin = xhigt(1)
16047 ihig = 1
16048 Do icrs = 2, jhig
16049 If (xhigt(icrs) < xmin) Then
16050 xmin = xhigt(icrs)
16051 ihig = icrs
16052 End If
16053 End Do
16054 !
16055 jlow = jlow + 1
16056 xlowt(jlow) = xhigt(ihig)
16057 xhigt(ihig) = xhigt(jhig)
16058 jhig = jhig - 1
16059 Else
16060
16061 xmax = xlowt(jlow)
16062 jlow = jlow - 1
16063 Do icrs = 1, jlow
16064 If (xlowt(icrs) > xmax) Then
16065 xwrk = xmax
16066 xmax = xlowt(icrs)
16067 xlowt(icrs) = xwrk
16068 End If
16069 End Do
16070 End If
16071 End If
16072 jlm2 = jlm1
16073 jlm1 = jlow
16074 jhm2 = jhm1
16075 jhm1 = jhig
16076 !
16077 ! We try to bring the number of values in the low values set
16078 ! closer to INTH.
16079 !
16080 Select Case (inth - jlow)
16081 Case (2 :)
16082 !
16083 ! Not enough values in low part, at least 2 are missing
16084 !
16085 inth = inth - jlow
16086 jlow = 0
16087 Select Case (jhig)
16088 !!!!! CASE DEFAULT
16089 !!!!! write (unit=*,fmt=*) "Assertion failed"
16090 !!!!! STOP
16091 !
16092 ! We make a special case when we have so few values in
16093 ! the high values set that it is bad performance to choose a pivot
16094 ! and apply the general algorithm.
16095 !
16096 Case (2)
16097 If (xhigt(1) <= xhigt(2)) Then
16098 jlow = jlow + 1
16099 xlowt(jlow) = xhigt(1)
16100 jlow = jlow + 1
16101 xlowt(jlow) = xhigt(2)
16102 Else
16103 jlow = jlow + 1
16104 xlowt(jlow) = xhigt(2)
16105 jlow = jlow + 1
16106 xlowt(jlow) = xhigt(1)
16107 End If
16108 Exit
16109 !
16110 Case (3)
16111 !
16112 !
16113 xwrk1 = xhigt(1)
16114 xwrk2 = xhigt(2)
16115 xwrk3 = xhigt(3)
16116 If (xwrk2 < xwrk1) Then
16117 xhigt(1) = xwrk2
16118 xhigt(2) = xwrk1
16119 xwrk2 = xwrk1
16120 End If
16121 If (xwrk2 > xwrk3) Then
16122 xhigt(3) = xwrk2
16123 xhigt(2) = xwrk3
16124 xwrk2 = xwrk3
16125 If (xwrk2 < xhigt(1)) Then
16126 xhigt(2) = xhigt(1)
16127 xhigt(1) = xwrk2
16128 End If
16129 End If
16130 jhig = 0
16131 Do icrs = jlow + 1, inth
16132 jhig = jhig + 1
16133 xlowt(icrs) = xhigt(jhig)
16134 End Do
16135 jlow = inth
16136 Exit
16137 !
16138 Case (4 :)
16139 !
16140 !
16141 ifin = jhig
16142 !
16143 ! One chooses a pivot from the 2 first values and the last one.
16144 ! This should ensure sufficient renewal between iterations to
16145 ! avoid worst case behavior effects.
16146 !
16147 xwrk1 = xhigt(1)
16148 xwrk2 = xhigt(2)
16149 xwrk3 = xhigt(ifin)
16150 If (xwrk2 < xwrk1) Then
16151 xhigt(1) = xwrk2
16152 xhigt(2) = xwrk1
16153 xwrk2 = xwrk1
16154 End If
16155 If (xwrk2 > xwrk3) Then
16156 xhigt(ifin) = xwrk2
16157 xhigt(2) = xwrk3
16158 xwrk2 = xwrk3
16159 If (xwrk2 < xhigt(1)) Then
16160 xhigt(2) = xhigt(1)
16161 xhigt(1) = xwrk2
16162 End If
16163 End If
16164 !
16165 xwrk1 = xhigt(1)
16166 jlow = jlow + 1
16167 xlowt(jlow) = xwrk1
16168 xpiv = xwrk1 + 0.5 * (xhigt(ifin) - xwrk1)
16169 !
16170 ! One takes values <= pivot to XLOWT
16171 ! Again, 2 parts, one where we take care of the remaining
16172 ! high values because we might still need them, and the
16173 ! other when we know that we will have more than enough
16174 ! low values in the end.
16175 !
16176 jhig = 0
16177 Do icrs = 2, ifin
16178 If (xhigt(icrs) <= xpiv) Then
16179 jlow = jlow + 1
16180 xlowt(jlow) = xhigt(icrs)
16181 If (jlow >= inth) Exit
16182 Else
16183 jhig = jhig + 1
16184 xhigt(jhig) = xhigt(icrs)
16185 End If
16186 End Do
16187 !
16188 Do icrs = icrs + 1, ifin
16189 If (xhigt(icrs) <= xpiv) Then
16190 jlow = jlow + 1
16191 xlowt(jlow) = xhigt(icrs)
16192 End If
16193 End Do
16194 End Select
16195 !
16196 !
16197 Case (1)
16198 !
16199 ! Only 1 value is missing in low part
16200 !
16201 xmin = xhigt(1)
16202 ihig = 1
16203 Do icrs = 2, jhig
16204 If (xhigt(icrs) < xmin) Then
16205 xmin = xhigt(icrs)
16206 ihig = icrs
16207 End If
16208 End Do
16209 !
16210 valnth = xhigt(ihig)
16211 Return
16212 !
16213 !
16214 Case (0)
16215 !
16216 ! Low part is exactly what we want
16217 !
16218 Exit
16219 !
16220 !
16221 Case (-5 : -1)
16222 !
16223 ! Only few values too many in low part
16224 !
16225 xhigt(1) = xlowt(1)
16226 ilow = 1 + inth - jlow
16227 Do icrs = 2, inth
16228 xwrk = xlowt(icrs)
16229 Do idcr = icrs - 1, max(1, ilow), - 1
16230 If (xwrk < xhigt(idcr)) Then
16231 xhigt(idcr + 1) = xhigt(idcr)
16232 Else
16233 Exit
16234 End If
16235 End Do
16236 xhigt(idcr + 1) = xwrk
16237 ilow = ilow + 1
16238 End Do
16239 !
16240 xwrk1 = xhigt(inth)
16241 ilow = 2 * inth - jlow
16242 Do icrs = inth + 1, jlow
16243 If (xlowt(icrs) < xwrk1) Then
16244 xwrk = xlowt(icrs)
16245 Do idcr = inth - 1, max(1, ilow), - 1
16246 If (xwrk >= xhigt(idcr)) Exit
16247 xhigt(idcr + 1) = xhigt(idcr)
16248 End Do
16249 xhigt(idcr + 1) = xlowt(icrs)
16250 xwrk1 = xhigt(inth)
16251 End If
16252 ilow = ilow + 1
16253 End Do
16254 !
16255 valnth = xhigt(inth)
16256 Return
16257 !
16258 !
16259 Case (: -6)
16260 !
16261 ! last case: too many values in low part
16262 !
16263
16264 imil = (jlow + 1) / 2
16265 ifin = jlow
16266 !
16267 ! One chooses a pivot from 1st, last, and middle values
16268 !
16269 If (xlowt(imil) < xlowt(1)) Then
16270 xwrk = xlowt(1)
16271 xlowt(1) = xlowt(imil)
16272 xlowt(imil) = xwrk
16273 End If
16274 If (xlowt(imil) > xlowt(ifin)) Then
16275 xwrk = xlowt(ifin)
16276 xlowt(ifin) = xlowt(imil)
16277 xlowt(imil) = xwrk
16278 If (xlowt(imil) < xlowt(1)) Then
16279 xwrk = xlowt(1)
16280 xlowt(1) = xlowt(imil)
16281 xlowt(imil) = xwrk
16282 End If
16283 End If
16284 If (ifin <= 3) Exit
16285 !
16286 xpiv = xlowt(1) + real(inth, sp) / real(jlow + inth, sp) * &
16287 (xlowt(ifin) - xlowt(1))
16288
16289 !
16290 ! One takes values > XPIV to XHIGT
16291 !
16292 jhig = 0
16293 jlow = 0
16294 !
16295 If (xlowt(ifin) > xpiv) Then
16296 icrs = 0
16297 Do
16298 icrs = icrs + 1
16299 If (xlowt(icrs) > xpiv) Then
16300 jhig = jhig + 1
16301 xhigt(jhig) = xlowt(icrs)
16302 If (icrs >= ifin) Exit
16303 Else
16304 jlow = jlow + 1
16305 xlowt(jlow) = xlowt(icrs)
16306 If (jlow >= inth) Exit
16307 End If
16308 End Do
16309 !
16310 If (icrs < ifin) Then
16311 Do
16312 icrs = icrs + 1
16313 If (xlowt(icrs) <= xpiv) Then
16314 jlow = jlow + 1
16315 xlowt(jlow) = xlowt(icrs)
16316 Else
16317 If (icrs >= ifin) Exit
16318 End If
16319 End Do
16320 End If
16321 Else
16322 Do icrs = 1, ifin
16323 If (xlowt(icrs) > xpiv) Then
16324 jhig = jhig + 1
16325 xhigt(jhig) = xlowt(icrs)
16326 Else
16327 jlow = jlow + 1
16328 xlowt(jlow) = xlowt(icrs)
16329 If (jlow >= inth) Exit
16330 End If
16331 End Do
16332 !
16333 Do icrs = icrs + 1, ifin
16334 If (xlowt(icrs) <= xpiv) Then
16335 jlow = jlow + 1
16336 xlowt(jlow) = xlowt(icrs)
16337 End If
16338 End Do
16339 End If
16340 !
16341 End Select
16342 !
16343 End Do
16344 !
16345 ! Now, we only need to find maximum of the 1:INTH set
16346 !
16347 valnth = maxval(xlowt(1 : inth))
16348 Return
16349 !
16350 !
16351 End Function r_valnth
16352
16353 Function i_valnth (XDONT, NORD) Result (valnth)
16354 ! Return NORDth value of XDONT, i.e fractile of order NORD/SIZE(XDONT).
16355 ! __________________________________________________________
16356 ! This routine uses a pivoting strategy such as the one of
16357 ! finding the median based on the quicksort algorithm, but
16358 ! we skew the pivot choice to try to bring it to NORD as
16359 ! fast as possible. It uses 2 temporary arrays, where it
16360 ! stores the indices of the values smaller than the pivot
16361 ! (ILOWT), and the indices of values larger than the pivot
16362 ! that we might still need later on (IHIGT). It iterates
16363 ! until it can bring the number of values in ILOWT to
16364 ! exactly NORD, and then finds the maximum of this set.
16365 ! Michel Olagnon - Aug. 2000
16366 ! __________________________________________________________
16367 ! __________________________________________________________
16368 Integer(kind = i4), Dimension (:), Intent (In) :: XDONT
16369 Integer(kind = i4) :: valnth
16370 Integer(kind = i4), Intent (In) :: NORD
16371 ! __________________________________________________________
16372 Integer(kind = i4), Dimension (SIZE(XDONT)) :: XLOWT, XHIGT
16373 Integer(kind = i4) :: XPIV, XWRK, XWRK1, XWRK2, XWRK3, XMIN, XMAX
16374 !
16375 Integer(kind = i4) :: NDON, JHIG, JLOW, IHIG
16376 Integer(kind = i4) :: IMIL, IFIN, ICRS, IDCR, ILOW
16377 Integer(kind = i4) :: JLM2, JLM1, JHM2, JHM1, INTH
16378 !
16379 ndon = SIZE (xdont)
16380 inth = max(min(nord, ndon), 1)
16381 !
16382 ! First loop is used to fill-in XLOWT, XHIGT at the same time
16383 !
16384 If (ndon < 2) Then
16385 If (inth == 1) valnth = xdont(1)
16386 Return
16387 End If
16388 !
16389 ! One chooses a pivot, best estimate possible to put fractile near
16390 ! mid-point of the set of low values.
16391 !
16392 If (xdont(2) < xdont(1)) Then
16393 xlowt(1) = xdont(2)
16394 xhigt(1) = xdont(1)
16395 Else
16396 xlowt(1) = xdont(1)
16397 xhigt(1) = xdont(2)
16398 End If
16399 !
16400 If (ndon < 3) Then
16401 If (inth == 1) valnth = xlowt(1)
16402 If (inth == 2) valnth = xhigt(1)
16403 Return
16404 End If
16405 !
16406 If (xdont(3) < xhigt(1)) Then
16407 xhigt(2) = xhigt(1)
16408 If (xdont(3) < xlowt(1)) Then
16409 xhigt(1) = xlowt(1)
16410 xlowt(1) = xdont(3)
16411 Else
16412 xhigt(1) = xdont(3)
16413 End If
16414 Else
16415 xhigt(2) = xdont(3)
16416 End If
16417 !
16418 If (ndon < 4) Then
16419 If (inth == 1) Then
16420 valnth = xlowt(1)
16421 Else
16422 valnth = xhigt(inth - 1)
16423 End If
16424 Return
16425 End If
16426 !
16427 If (xdont(ndon) < xhigt(1)) Then
16428 xhigt(3) = xhigt(2)
16429 xhigt(2) = xhigt(1)
16430 If (xdont(ndon) < xlowt(1)) Then
16431 xhigt(1) = xlowt(1)
16432 xlowt(1) = xdont(ndon)
16433 Else
16434 xhigt(1) = xdont(ndon)
16435 End If
16436 Else
16437 xhigt(3) = xdont(ndon)
16438 End If
16439 !
16440 If (ndon < 5) Then
16441 If (inth == 1) Then
16442 valnth = xlowt(1)
16443 Else
16444 valnth = xhigt(inth - 1)
16445 End If
16446 Return
16447 End If
16448 !
16449
16450 jlow = 1
16451 jhig = 3
16452 xpiv = xlowt(1) + int(real(2 * inth, sp) / real(ndon + inth, sp), i4) * (xhigt(3) - xlowt(1))
16453 If (xpiv >= xhigt(1)) Then
16454 xpiv = xlowt(1) + int(real(2 * inth, sp) / real(ndon + inth, sp), i4) * &
16455 (xhigt(2) - xlowt(1))
16456 If (xpiv >= xhigt(1)) &
16457 xpiv = xlowt(1) + int(real(2 * inth, sp) / real(ndon + inth, sp), i4) * &
16458 (xhigt(1) - xlowt(1))
16459 End If
16460 !
16461 ! One puts values > pivot in the end and those <= pivot
16462 ! at the beginning. This is split in 2 cases, so that
16463 ! we can skip the loop test a number of times.
16464 ! As we are also filling in the work arrays at the same time
16465 ! we stop filling in the XHIGT array as soon as we have more
16466 ! than enough values in XLOWT.
16467 !
16468 !
16469 If (xdont(ndon) > xpiv) Then
16470 icrs = 3
16471 Do
16472 icrs = icrs + 1
16473 If (xdont(icrs) > xpiv) Then
16474 If (icrs >= ndon) Exit
16475 jhig = jhig + 1
16476 xhigt(jhig) = xdont(icrs)
16477 Else
16478 jlow = jlow + 1
16479 xlowt(jlow) = xdont(icrs)
16480 If (jlow >= inth) Exit
16481 End If
16482 End Do
16483 !
16484 ! One restricts further processing because it is no use
16485 ! to store more high values
16486 !
16487 If (icrs < ndon - 1) Then
16488 Do
16489 icrs = icrs + 1
16490 If (xdont(icrs) <= xpiv) Then
16491 jlow = jlow + 1
16492 xlowt(jlow) = xdont(icrs)
16493 Else If (icrs >= ndon) Then
16494 Exit
16495 End If
16496 End Do
16497 End If
16498 !
16499 !
16500 Else
16501 !
16502 ! Same as above, but this is not as easy to optimize, so the
16503 ! DO-loop is kept
16504 !
16505 Do icrs = 4, ndon - 1
16506 If (xdont(icrs) > xpiv) Then
16507 jhig = jhig + 1
16508 xhigt(jhig) = xdont(icrs)
16509 Else
16510 jlow = jlow + 1
16511 xlowt(jlow) = xdont(icrs)
16512 If (jlow >= inth) Exit
16513 End If
16514 End Do
16515 !
16516 If (icrs < ndon - 1) Then
16517 Do
16518 icrs = icrs + 1
16519 If (xdont(icrs) <= xpiv) Then
16520 If (icrs >= ndon) Exit
16521 jlow = jlow + 1
16522 xlowt(jlow) = xdont(icrs)
16523 End If
16524 End Do
16525 End If
16526 End If
16527 !
16528 jlm2 = 0
16529 jlm1 = 0
16530 jhm2 = 0
16531 jhm1 = 0
16532 Do
16533 If (jlm2 == jlow .And. jhm2 == jhig) Then
16534 !
16535 ! We are oscillating. Perturbate by bringing JLOW closer by one
16536 ! to INTH
16537 !
16538 If (inth > jlow) Then
16539 xmin = xhigt(1)
16540 ihig = 1
16541 Do icrs = 2, jhig
16542 If (xhigt(icrs) < xmin) Then
16543 xmin = xhigt(icrs)
16544 ihig = icrs
16545 End If
16546 End Do
16547 !
16548 jlow = jlow + 1
16549 xlowt(jlow) = xhigt(ihig)
16550 xhigt(ihig) = xhigt(jhig)
16551 jhig = jhig - 1
16552 Else
16553
16554 xmax = xlowt(jlow)
16555 jlow = jlow - 1
16556 Do icrs = 1, jlow
16557 If (xlowt(icrs) > xmax) Then
16558 xwrk = xmax
16559 xmax = xlowt(icrs)
16560 xlowt(icrs) = xwrk
16561 End If
16562 End Do
16563 End If
16564 End If
16565 jlm2 = jlm1
16566 jlm1 = jlow
16567 jhm2 = jhm1
16568 jhm1 = jhig
16569 !
16570 ! We try to bring the number of values in the low values set
16571 ! closer to INTH.
16572 !
16573 Select Case (inth - jlow)
16574 Case (2 :)
16575 !
16576 ! Not enough values in low part, at least 2 are missing
16577 !
16578 inth = inth - jlow
16579 jlow = 0
16580 Select Case (jhig)
16581 !!!!! CASE DEFAULT
16582 !!!!! write (unit=*,fmt=*) "Assertion failed"
16583 !!!!! STOP
16584 !
16585 ! We make a special case when we have so few values in
16586 ! the high values set that it is bad performance to choose a pivot
16587 ! and apply the general algorithm.
16588 !
16589 Case (2)
16590 If (xhigt(1) <= xhigt(2)) Then
16591 jlow = jlow + 1
16592 xlowt(jlow) = xhigt(1)
16593 jlow = jlow + 1
16594 xlowt(jlow) = xhigt(2)
16595 Else
16596 jlow = jlow + 1
16597 xlowt(jlow) = xhigt(2)
16598 jlow = jlow + 1
16599 xlowt(jlow) = xhigt(1)
16600 End If
16601 Exit
16602 !
16603 Case (3)
16604 !
16605 !
16606 xwrk1 = xhigt(1)
16607 xwrk2 = xhigt(2)
16608 xwrk3 = xhigt(3)
16609 If (xwrk2 < xwrk1) Then
16610 xhigt(1) = xwrk2
16611 xhigt(2) = xwrk1
16612 xwrk2 = xwrk1
16613 End If
16614 If (xwrk2 > xwrk3) Then
16615 xhigt(3) = xwrk2
16616 xhigt(2) = xwrk3
16617 xwrk2 = xwrk3
16618 If (xwrk2 < xhigt(1)) Then
16619 xhigt(2) = xhigt(1)
16620 xhigt(1) = xwrk2
16621 End If
16622 End If
16623 jhig = 0
16624 Do icrs = jlow + 1, inth
16625 jhig = jhig + 1
16626 xlowt(icrs) = xhigt(jhig)
16627 End Do
16628 jlow = inth
16629 Exit
16630 !
16631 Case (4 :)
16632 !
16633 !
16634 ifin = jhig
16635 !
16636 ! One chooses a pivot from the 2 first values and the last one.
16637 ! This should ensure sufficient renewal between iterations to
16638 ! avoid worst case behavior effects.
16639 !
16640 xwrk1 = xhigt(1)
16641 xwrk2 = xhigt(2)
16642 xwrk3 = xhigt(ifin)
16643 If (xwrk2 < xwrk1) Then
16644 xhigt(1) = xwrk2
16645 xhigt(2) = xwrk1
16646 xwrk2 = xwrk1
16647 End If
16648 If (xwrk2 > xwrk3) Then
16649 xhigt(ifin) = xwrk2
16650 xhigt(2) = xwrk3
16651 xwrk2 = xwrk3
16652 If (xwrk2 < xhigt(1)) Then
16653 xhigt(2) = xhigt(1)
16654 xhigt(1) = xwrk2
16655 End If
16656 End If
16657 !
16658 xwrk1 = xhigt(1)
16659 jlow = jlow + 1
16660 xlowt(jlow) = xwrk1
16661 xpiv = xwrk1 + (xhigt(ifin) - xwrk1) / 2
16662 !
16663 ! One takes values <= pivot to XLOWT
16664 ! Again, 2 parts, one where we take care of the remaining
16665 ! high values because we might still need them, and the
16666 ! other when we know that we will have more than enough
16667 ! low values in the end.
16668 !
16669 jhig = 0
16670 Do icrs = 2, ifin
16671 If (xhigt(icrs) <= xpiv) Then
16672 jlow = jlow + 1
16673 xlowt(jlow) = xhigt(icrs)
16674 If (jlow >= inth) Exit
16675 Else
16676 jhig = jhig + 1
16677 xhigt(jhig) = xhigt(icrs)
16678 End If
16679 End Do
16680 !
16681 Do icrs = icrs + 1, ifin
16682 If (xhigt(icrs) <= xpiv) Then
16683 jlow = jlow + 1
16684 xlowt(jlow) = xhigt(icrs)
16685 End If
16686 End Do
16687 End Select
16688 !
16689 !
16690 Case (1)
16691 !
16692 ! Only 1 value is missing in low part
16693 !
16694 xmin = xhigt(1)
16695 ihig = 1
16696 Do icrs = 2, jhig
16697 If (xhigt(icrs) < xmin) Then
16698 xmin = xhigt(icrs)
16699 ihig = icrs
16700 End If
16701 End Do
16702 !
16703 valnth = xhigt(ihig)
16704 Return
16705 !
16706 !
16707 Case (0)
16708 !
16709 ! Low part is exactly what we want
16710 !
16711 Exit
16712 !
16713 !
16714 Case (-5 : -1)
16715 !
16716 ! Only few values too many in low part
16717 !
16718 xhigt(1) = xlowt(1)
16719 ilow = 1 + inth - jlow
16720 Do icrs = 2, inth
16721 xwrk = xlowt(icrs)
16722 Do idcr = icrs - 1, max(1, ilow), - 1
16723 If (xwrk < xhigt(idcr)) Then
16724 xhigt(idcr + 1) = xhigt(idcr)
16725 Else
16726 Exit
16727 End If
16728 End Do
16729 xhigt(idcr + 1) = xwrk
16730 ilow = ilow + 1
16731 End Do
16732 !
16733 xwrk1 = xhigt(inth)
16734 ilow = 2 * inth - jlow
16735 Do icrs = inth + 1, jlow
16736 If (xlowt(icrs) < xwrk1) Then
16737 xwrk = xlowt(icrs)
16738 Do idcr = inth - 1, max(1, ilow), - 1
16739 If (xwrk >= xhigt(idcr)) Exit
16740 xhigt(idcr + 1) = xhigt(idcr)
16741 End Do
16742 xhigt(idcr + 1) = xlowt(icrs)
16743 xwrk1 = xhigt(inth)
16744 End If
16745 ilow = ilow + 1
16746 End Do
16747 !
16748 valnth = xhigt(inth)
16749 Return
16750 !
16751 !
16752 Case (: -6)
16753 !
16754 ! last case: too many values in low part
16755 !
16756
16757 imil = (jlow + 1) / 2
16758 ifin = jlow
16759 !
16760 ! One chooses a pivot from 1st, last, and middle values
16761 !
16762 If (xlowt(imil) < xlowt(1)) Then
16763 xwrk = xlowt(1)
16764 xlowt(1) = xlowt(imil)
16765 xlowt(imil) = xwrk
16766 End If
16767 If (xlowt(imil) > xlowt(ifin)) Then
16768 xwrk = xlowt(ifin)
16769 xlowt(ifin) = xlowt(imil)
16770 xlowt(imil) = xwrk
16771 If (xlowt(imil) < xlowt(1)) Then
16772 xwrk = xlowt(1)
16773 xlowt(1) = xlowt(imil)
16774 xlowt(imil) = xwrk
16775 End If
16776 End If
16777 If (ifin <= 3) Exit
16778 !
16779 xpiv = xlowt(1) + int(real(inth, sp) / real(jlow + inth, sp), i4) * &
16780 (xlowt(ifin) - xlowt(1))
16781
16782 !
16783 ! One takes values > XPIV to XHIGT
16784 !
16785 jhig = 0
16786 jlow = 0
16787 !
16788 If (xlowt(ifin) > xpiv) Then
16789 icrs = 0
16790 Do
16791 icrs = icrs + 1
16792 If (xlowt(icrs) > xpiv) Then
16793 jhig = jhig + 1
16794 xhigt(jhig) = xlowt(icrs)
16795 If (icrs >= ifin) Exit
16796 Else
16797 jlow = jlow + 1
16798 xlowt(jlow) = xlowt(icrs)
16799 If (jlow >= inth) Exit
16800 End If
16801 End Do
16802 !
16803 If (icrs < ifin) Then
16804 Do
16805 icrs = icrs + 1
16806 If (xlowt(icrs) <= xpiv) Then
16807 jlow = jlow + 1
16808 xlowt(jlow) = xlowt(icrs)
16809 Else
16810 If (icrs >= ifin) Exit
16811 End If
16812 End Do
16813 End If
16814 Else
16815 Do icrs = 1, ifin
16816 If (xlowt(icrs) > xpiv) Then
16817 jhig = jhig + 1
16818 xhigt(jhig) = xlowt(icrs)
16819 Else
16820 jlow = jlow + 1
16821 xlowt(jlow) = xlowt(icrs)
16822 If (jlow >= inth) Exit
16823 End If
16824 End Do
16825 !
16826 Do icrs = icrs + 1, ifin
16827 If (xlowt(icrs) <= xpiv) Then
16828 jlow = jlow + 1
16829 xlowt(jlow) = xlowt(icrs)
16830 End If
16831 End Do
16832 End If
16833 !
16834 End Select
16835 !
16836 End Do
16837 !
16838 ! Now, we only need to find maximum of the 1:INTH set
16839 !
16840 valnth = maxval(xlowt(1 : inth))
16841 Return
16842 !
16843 !
16844 End Function i_valnth
16845
16846END MODULE mo_orderpack
Random permutation ranking.
Find N-th value in array from insertion sort.
Median index of skewed-pivot with quicksort ranking.
Nth index of skewed-pivot with quicksort ranking.
Partial insertion sort ranking,.
Insertion sort ranking.
Merge-sort ranking (unoptimized)
Merge-sort ranking.
Multiplicity of array values.
Find median value of array (case for even elements)
Skewed-pivot with quicksort ranking (reversed).
Skewed-pivot with quicksort ranking (unoptimized).
Quicksort ranking, with insertion sort at last step (unoptimized)
Insertion sort ranking (unoptimized).
Skewed-pivot with quicksort ranking.
Gives the indeces that would sort an array in ascending order.
Sorts the input array in ascending order.
Merge-sort ranking, with removal of duplicate entries (reversed).
Partial quicksort/insertion sort ranking, with removal of duplicate entries.
Merge-sort ranking, with removal of duplicate entries.
Merge-sort unique inverse ranking.
Find median value of array.
Find N-th value in array from quicksort.
Comparison of real values.
Definition mo_utils.F90:284
Comparison of real values: a <= b.
Definition mo_utils.F90:299
Comparison of real values for inequality.
Definition mo_utils.F90:289
Define number representations.
Definition mo_kind.F90:17
integer, parameter sp
Single Precision Real Kind.
Definition mo_kind.F90:44
integer, parameter i4
4 Byte Integer Kind
Definition mo_kind.F90:40
integer, parameter dp
Double Precision Real Kind.
Definition mo_kind.F90:46
Sort and ranking routines.
General utilities for the CHS library.
Definition mo_utils.F90:20