Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ModSortSearch.F90
Go to the documentation of this file.
1 ! *********************************************************************
2 ! * Rocstar Simulation Suite *
3 ! * Copyright@2015, Illinois Rocstar LLC. All rights reserved. *
4 ! * *
5 ! * Illinois Rocstar LLC *
6 ! * Champaign, IL *
7 ! * www.illinoisrocstar.com *
8 ! * sales@illinoisrocstar.com *
9 ! * *
10 ! * License: See LICENSE file in top level of distribution package or *
11 ! * http://opensource.org/licenses/NCSA *
12 ! *********************************************************************
13 ! *********************************************************************
14 ! * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
15 ! * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES *
16 ! * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND *
17 ! * NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR *
18 ! * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
19 ! * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
20 ! * Arising FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
21 ! * USE OR OTHER DEALINGS WITH THE SOFTWARE. *
22 ! *********************************************************************
23 ! ******************************************************************************
24 !
25 ! Purpose: Collection of procedures to sort and search arrays.
26 !
27 ! Description: none
28 !
29 ! Notes:
30 ! 1. The procedures in this modules have been collected from various sources.
31 ! See remarks in the respective procedures.
32 !
33 ! ******************************************************************************
34 !
35 ! $Id: ModSortSearch.F90,v 1.18 2008/12/06 08:44:19 mtcampbe Exp $
36 !
37 ! Copyright: (c) 2001-2005 by the University of Illinois
38 !
39 ! ******************************************************************************
40 
42 
43  USE modglobal, ONLY: t_global
44  USE moddatatypes
45  USE modparameters
46  USE moderror
47 
48  IMPLICIT NONE
49 
50 ! ******************************************************************************
51 ! Declarations and definitions
52 ! ******************************************************************************
53 
54 ! ==============================================================================
55 ! Local variables
56 ! ==============================================================================
57 
58  INTEGER, PARAMETER :: ELEMENT_NOT_FOUND = -1 ! must be < 0
59  CHARACTER(CHRLEN), PARAMETER, PRIVATE :: &
60  RCSIdentString = '$RCSfile: ModSortSearch.F90,v $ $Revision: 1.18 $'
61 
62 ! ******************************************************************************
63 ! Module subroutines
64 ! ******************************************************************************
65 
66  CONTAINS
67 
68 
69 
70 
71 ! ******************************************************************************
72 !
73 ! Procedure: BinarySearchInteger.F90
74 !
75 ! Purpose: Search array with elements in ascending order using binary search.
76 !
77 ! Description: See appropriate textbooks.
78 !
79 ! Input:
80 ! a Array with elements in ascending order
81 ! n Size of array
82 ! v Value which is being searched for
83 !
84 ! Output:
85 ! i Location of v in a
86 ! j Lower index if value was not found (optional)
87 !
88 ! Notes:
89 ! 1. If v is not in a, the error flag ELEMENT_NOT_FOUND is returned.
90 ! 2. The optional argument j gives lower index if value was not found, and
91 ! CRAZY_VALUE_INT if the value was found. It is important to note that
92 ! this lower index can exceed n, the dimension of the array being searched.
93 ! For this reason, it is important to make sure j is checked before it is
94 ! used to access an array also dimensioned with n.
95 !
96 ! ******************************************************************************
97 
98 SUBROUTINE binarysearchinteger(a,n,v,i,j)
99 
100  IMPLICIT NONE
101 
102 ! ******************************************************************************
103 ! Declarations and definitions
104 ! ******************************************************************************
105 
106 ! ==============================================================================
107 ! Parameters
108 ! ==============================================================================
109 
110  INTEGER, INTENT(IN) :: n,v
111  INTEGER, INTENT(IN) :: a(n)
112  INTEGER, INTENT(OUT) :: i
113  INTEGER, INTENT(INOUT), OPTIONAL :: j
114 
115 ! ==============================================================================
116 ! Local variables
117 ! ==============================================================================
118 
119  INTEGER :: il,im,iu
120 
121 ! ******************************************************************************
122 ! Start
123 ! ******************************************************************************
124 
125  il = 1 ! initialise lower limit
126  iu = n ! initialise upper limit
127 
128  DO
129  im = (iu + il)/2 ! compute midpoint
130 
131  IF ( v < a(im) ) THEN ! eliminate upper half
132  iu = im - 1
133  ELSE IF ( v > a(im) ) THEN ! eliminate lower half
134  il = im + 1
135  ELSE ! found value
136  i = im
137 
138  IF ( present(j) .EQV. .true. ) THEN
139  j = crazy_value_int
140  END IF ! PRESENT
141 
142  EXIT
143  END IF ! v
144 
145  IF ( iu < il ) THEN ! element not found
146  i = element_not_found
147 
148  IF ( present(j) .EQV. .true. ) THEN
149  j = il
150  END IF ! PRESENT
151 
152  EXIT
153  END IF ! iu
154  END DO ! <empty>
155 
156 ! ******************************************************************************
157 ! End
158 ! ******************************************************************************
159 
160 END SUBROUTINE binarysearchinteger
161 
162 
163 
164 
165 
166 
167 ! ******************************************************************************
168 !
169 ! Purpose: Cycle list of integers until condition of equality is met.
170 !
171 ! Description: None.
172 !
173 ! Input:
174 ! a Array containing n elements
175 ! na Number of elements in array a
176 ! i Location at a where value must be located
177 ! v Target value in a at location i
178 !
179 ! Output:
180 ! a Array cycled such that a(i) = v
181 !
182 ! Notes:
183 ! 1. This routine does not check that v actually exists in a, so it is up to
184 ! you to make sure before calling this routine!
185 !
186 ! ******************************************************************************
187 
188  SUBROUTINE cyclelist(a,na,i,v)
189 
190  IMPLICIT NONE
191 
192 ! ******************************************************************************
193 ! Declarations and definitions
194 ! ******************************************************************************
195 
196 ! ==============================================================================
197 ! Parameters
198 ! ==============================================================================
199 
200  INTEGER, INTENT(IN) :: i,na,v
201  INTEGER, INTENT(INOUT) :: a(na)
202 
203 ! ==============================================================================
204 ! Locals
205 ! ==============================================================================
206 
207  INTEGER :: j,k,w
208 
209 ! ******************************************************************************
210 ! Start
211 ! ******************************************************************************
212 
213  DO j = 1,na-1
214  IF ( a(i) /= v ) THEN
215  w = a(na)
216 
217  DO k = na,2,-1
218  a(k) = a(k-1)
219  END DO ! k
220 
221  a(1) = w
222  ELSE
223  EXIT
224  END IF ! a
225  END DO ! j
226 
227  END SUBROUTINE cyclelist
228 
229 
230 
231 
232 
233 
234 ! ******************************************************************************
235 !
236 ! Purpose: Find duplicated elements of sorted integer arrays a and b and
237 ! store in array c, while keeping all elements in original arrays.
238 !
239 ! Description: None.
240 !
241 ! Input:
242 ! a Array
243 ! na Number of elements in array a
244 ! b Array, must be sorted in increasing order
245 ! nb Number of elements in array b
246 ! c Array
247 ! ncMax Size of array c
248 !
249 ! Output:
250 ! c Array c with duplicated elements on a and b
251 ! nc Number of elements in array c
252 ! errorFlag Error flag
253 !
254 ! Notes:
255 ! 1. List b must be sorted in increasing order on entry. List a, strictly
256 ! speaking must not be sorted. If a is not sorted, then the array c will
257 ! not be sorted either.
258 !
259 ! ******************************************************************************
260 
261  SUBROUTINE findcommonsortedintegers(a,na,b,nb,c,ncMax,nc,errorFlag)
262 
263  IMPLICIT NONE
264 
265 ! ******************************************************************************
266 ! Declarations and definitions
267 ! ******************************************************************************
268 
269 ! ==============================================================================
270 ! Parameters
271 ! ==============================================================================
272 
273  INTEGER, INTENT(IN) :: na,nb,ncmax
274  INTEGER, INTENT(OUT) :: nc,errorflag
275  INTEGER, INTENT(IN) :: a(na),b(nb)
276  INTEGER, INTENT(OUT) :: c(ncmax)
277 
278 ! ==============================================================================
279 ! Locals
280 ! ==============================================================================
281 
282  INTEGER :: ia,iloc
283 
284 ! ******************************************************************************
285 ! Start
286 ! ******************************************************************************
287 
288  errorflag = err_none
289 
290  nc = 0
291 
292  ia = 1
293 
294  emptyloop: DO
295  IF ( nb > 1 ) THEN
296  CALL binarysearchinteger(b(1:nb),nb,a(ia),iloc)
297  ELSE
298  IF ( b(1) == a(ia) ) THEN
299  iloc = element_not_found + 1 ! Set to anything but ELEMENT_NOT_FOUND
300  ELSE
301  iloc = element_not_found
302  END IF ! b(1)
303  END IF ! nb
304 
305  IF ( iloc /= element_not_found ) THEN
306  nc = nc + 1
307 
308  IF ( nc > ncmax ) THEN
309  errorflag = err_none - 1 ! Set to anything but ERR_NONE
310  EXIT emptyloop
311  END IF ! ic
312 
313  c(nc) = a(ia)
314  END IF ! iLoc
315 
316  ia = ia + 1
317 
318  IF ( ia > na ) THEN
319  EXIT emptyloop
320  END IF ! ia
321  END DO emptyloop
322 
323  END SUBROUTINE findcommonsortedintegers
324 
325 
326 
327 
328 
329 
330 ! ******************************************************************************
331 !
332 ! Purpose: Merge elements of two sorted elements of integer arrays a of size n.
333 !
334 ! Description: None.
335 !
336 ! Input:
337 ! na Number of elements in array a
338 ! nb Number of elements in array b
339 ! a Array containing sorted elements
340 ! b Array containing sorted elements
341 ! nm Number of elements in array m
342 ! m Array (empty)
343 !
344 ! Output:
345 ! im Number of elements in array m
346 ! m Array containing merged elements
347 !
348 ! Notes:
349 ! 1. This procedure results in a unique list in the sense that each element
350 ! in the merged list only appears once.
351 ! 2. It is easier to remove duplicate elements from the lists before merging
352 ! them than dealing with duplicate elements during merging.
353 !
354 ! ******************************************************************************
355 
356  SUBROUTINE mergesortedintegers(global,na,nb,a,b,nm,im,m)
357 
358  IMPLICIT NONE
359 
360 ! ******************************************************************************
361 ! Declarations and definitions
362 ! ******************************************************************************
363 
364 ! ==============================================================================
365 ! Parameters
366 ! ==============================================================================
367 
368  INTEGER, INTENT(IN) :: na,nb,nm
369  INTEGER, INTENT(IN) :: a(na),b(nb)
370  TYPE(t_global), POINTER :: global
371 
372  INTEGER, INTENT(OUT) :: im
373  INTEGER, INTENT(OUT) :: m(nm)
374 
375 ! ==============================================================================
376 ! Locals
377 ! ==============================================================================
378 
379  INTEGER :: i,ia,ib,na2,nb2,tbi
380  INTEGER :: a2(na),b2(nb)
381 
382 ! ******************************************************************************
383 ! Start
384 ! ******************************************************************************
385 
386 ! Eliminate duplicate elements from lists
387 
388  a2(1:na) = a(1:na)
389  b2(1:nb) = b(1:nb)
390 
391  CALL simplifysortedintegers(a2,na,na2)
392  CALL simplifysortedintegers(b2,nb,nb2)
393 
394 ! Initialize
395 
396  m(1:nm) = 0
397 
398  ia = 1
399  ib = 1
400  im = 0
401 
402 ! Traverse both sorted lists and insert smaller value into m
403 
404  DO
405  IF ( ia <= na2 .AND. ib <= nb2 ) THEN
406  IF ( a2(ia) > b2(ib) ) THEN
407  tbi = b2(ib)
408  ib = ib + 1
409  ELSE
410  tbi = a2(ia)
411  ia = ia + 1
412  END IF ! a2(ia)
413 
414  IF ( im == 0 ) THEN
415  im = 1
416  m(im) = tbi
417  ELSE
418  IF ( im < nm ) THEN
419  IF ( tbi /= m(im) ) THEN
420  im = im + 1
421  m(im) = tbi
422  END IF ! tbi
423  ELSE
424  CALL errorstop(global,err_merge_sorted,__line__)
425  END IF ! im
426  END IF ! im
427  ELSE
428  EXIT
429  END IF ! ia ...
430 
431  END DO ! <empty>
432 
433 ! Now that one of the original lists was traversed completely, fill in
434 ! the remainder of m from other sorted list
435 
436  IF ( ia <= na2 ) THEN
437  DO i = ia,na2
438  IF ( a2(i) /= m(im) ) THEN ! do not duplicate element
439  im = im + 1
440  m(im) = a2(i)
441  END IF ! a2(i)
442  END DO ! i
443  ELSE
444  DO i = ib,nb2
445  IF ( b2(i) /= m(im) ) THEN ! do not duplicate element
446  im = im + 1
447  m(im) = b2(i)
448  END IF ! b2(i)
449  END DO ! i
450  END IF ! ia
451 
452  END SUBROUTINE mergesortedintegers
453 
454 
455 
456 
457 
458 
459 ! ******************************************************************************
460 !
461 ! Procedure: QuickSortInteger.F90
462 !
463 ! Purpose: Sort elements of integer array a of size n into ascending order.
464 !
465 ! Description: Uses quicksort method.
466 !
467 ! Input:
468 ! a Array containing unsorted elements
469 ! n Number of elements in array a
470 !
471 ! Output:
472 ! a Array containing sorted elements
473 !
474 ! Notes:
475 ! 1. Taken from WWW, cannot remember where... Seems to originate from
476 ! Nicklaus Wirths book, see remark below.
477 ! 2. No modifications to original, apart from a few cosmetic changes and
478 ! from deletion of second array which was also being sorted along with a.
479 !
480 ! ******************************************************************************
481 
482  SUBROUTINE quicksortinteger(a,n)
483 
484 ! NON-RECURSIVE STACK VERSION OF QUICKSORT FROM N.WIRTHS PASCAL
485 ! BOOK, 'ALGORITHMS + DATA STRUCTURES = PROGRAMS'.
486 
487  IMPLICIT NONE
488 
489  INTEGER, INTENT(IN) :: n
490  INTEGER, INTENT(INOUT) :: a(n)
491 
492 ! Local Variables
493 
494  INTEGER :: i, j, k, l, r, s, stackl(50), stackr(50)
495  INTEGER :: w, x
496 
497  s = 1
498  stackl(1) = 1
499  stackr(1) = n
500 
501 ! KEEP TAKING THE TOP REQUEST FROM THE STACK UNTIL S = 0.
502 
503  10 CONTINUE
504  l = stackl(s)
505  r = stackr(s)
506  s = s - 1
507 
508 ! KEEP SPLITTING A(L), ... , A(R) UNTIL L >= R.
509 
510  20 CONTINUE
511  i = l
512  j = r
513  k = (l+r) / 2
514  x = a(k)
515 
516 ! REPEAT UNTIL I > J.
517 
518  DO
519  DO
520  IF (a(i).LT.x) THEN ! Search from lower end
521  i = i + 1
522  cycle
523  ELSE
524  EXIT
525  END IF
526  END DO
527 
528  DO
529  IF (x.LT.a(j)) THEN ! Search from upper end
530  j = j - 1
531  cycle
532  ELSE
533  EXIT
534  END IF
535  END DO
536 
537  IF (i.LE.j) THEN ! Swap positions i & j
538  w = a(i)
539  a(i) = a(j)
540  a(j) = w
541  i = i + 1
542  j = j - 1
543  IF (i.GT.j) EXIT
544  ELSE
545  EXIT
546  END IF
547  END DO
548 
549  IF (j-l.GE.r-i) THEN
550  IF (l.LT.j) THEN
551  s = s + 1
552  stackl(s) = l
553  stackr(s) = j
554  END IF
555  l = i
556  ELSE
557  IF (i.LT.r) THEN
558  s = s + 1
559  stackl(s) = i
560  stackr(s) = r
561  END IF
562  r = j
563  END IF
564 
565  IF (l.LT.r) go to 20
566  IF (s.NE.0) go to 10
567 
568  RETURN
569 
570  END SUBROUTINE quicksortinteger
571 
572 
573 
574 
575 
576 ! ******************************************************************************
577 !
578 ! Procedure: QuickSortIntegerInteger.F90
579 !
580 ! Purpose: Sort elements of integer array a of size n into ascending order and
581 ! sort b along with it.
582 !
583 ! Description: Uses quicksort method.
584 !
585 ! Input:
586 ! a Array containing unsorted elements
587 ! b Integer array
588 ! n Number of elements in array a
589 !
590 ! Output:
591 ! a Array containing sorted elements
592 ! b Integer array
593 !
594 ! Notes:
595 ! 1. Taken from WWW, cannot remember where... Seems to originate from
596 ! Nicklaus Wirths book, see remark below.
597 ! 2. No modifications to original, apart from a few cosmetic changes and
598 ! from deletion of second array which was also being sorted along with a.
599 !
600 ! ******************************************************************************
601 
602  SUBROUTINE quicksortintegerinteger(a,b,n)
603 
604 ! NON-RECURSIVE STACK VERSION OF QUICKSORT FROM N.WIRTHS PASCAL
605 ! BOOK, 'ALGORITHMS + DATA STRUCTURES = PROGRAMS'.
606 
607  IMPLICIT NONE
608 
609  INTEGER, INTENT(IN) :: n
610  INTEGER, INTENT(INOUT) :: a(n),b(n)
611 
612 ! Local Variables
613 
614  INTEGER :: i, j, k, l, r, s, stackl(50), stackr(50)
615  INTEGER :: v, w, x
616 
617  s = 1
618  stackl(1) = 1
619  stackr(1) = n
620 
621 ! KEEP TAKING THE TOP REQUEST FROM THE STACK UNTIL S = 0.
622 
623  10 CONTINUE
624  l = stackl(s)
625  r = stackr(s)
626  s = s - 1
627 
628 ! KEEP SPLITTING A(L), ... , A(R) UNTIL L >= R.
629 
630  20 CONTINUE
631  i = l
632  j = r
633  k = (l+r) / 2
634  x = a(k)
635 
636 ! REPEAT UNTIL I > J.
637 
638  DO
639  DO
640  IF (a(i).LT.x) THEN ! Search from lower end
641  i = i + 1
642  cycle
643  ELSE
644  EXIT
645  END IF
646  END DO
647 
648  DO
649  IF (x.LT.a(j)) THEN ! Search from upper end
650  j = j - 1
651  cycle
652  ELSE
653  EXIT
654  END IF
655  END DO
656 
657  IF (i.LE.j) THEN ! Swap positions i & j
658  w = a(i)
659  a(i) = a(j)
660  a(j) = w
661  v = b(i)
662  b(i) = b(j)
663  b(j) = v
664  i = i + 1
665  j = j - 1
666  IF (i.GT.j) EXIT
667  ELSE
668  EXIT
669  END IF
670  END DO
671 
672  IF (j-l.GE.r-i) THEN
673  IF (l.LT.j) THEN
674  s = s + 1
675  stackl(s) = l
676  stackr(s) = j
677  END IF
678  l = i
679  ELSE
680  IF (i.LT.r) THEN
681  s = s + 1
682  stackl(s) = i
683  stackr(s) = r
684  END IF
685  r = j
686  END IF
687 
688  IF (l.LT.r) go to 20
689  IF (s.NE.0) go to 10
690 
691  RETURN
692 
693  END SUBROUTINE quicksortintegerinteger
694 
695 
696 
697 
698 
699 
700 ! ******************************************************************************
701 !
702 ! Purpose: Sort elements of double-precision array a of size n into ascending
703 ! order.
704 !
705 ! Description: Uses quicksort method.
706 !
707 ! Input:
708 ! a Array containing unsorted elements
709 ! n Number of elements in array a
710 !
711 ! Output:
712 ! a Array containing sorted elements
713 !
714 ! Notes:
715 ! 1. Taken from WWW, cannot remember where... Seems to originate from
716 ! Nicklaus Wirths book, see remark below.
717 ! 2. No modifications to original, apart from a few cosmetic changes and
718 ! from deletion of second array which was also being sorted along with a.
719 !
720 ! ******************************************************************************
721 
722  SUBROUTINE quicksortrfreal(a,n)
723 
724 ! NON-RECURSIVE STACK VERSION OF QUICKSORT FROM N.WIRTHS PASCAL
725 ! BOOK, 'ALGORITHMS + DATA STRUCTURES = PROGRAMS'.
726 
727  IMPLICIT NONE
728 
729  INTEGER, INTENT(IN) :: n
730  REAL(KIND=RFREAL), INTENT(INOUT) :: a(n)
731 
732 ! Local Variables
733 
734  INTEGER :: i, j, k, l, r, s, stackl(50), stackr(50)
735  REAL(KIND=RFREAL) :: w, x
736 
737  s = 1
738  stackl(1) = 1
739  stackr(1) = n
740 
741 ! KEEP TAKING THE TOP REQUEST FROM THE STACK UNTIL S = 0.
742 
743  10 CONTINUE
744  l = stackl(s)
745  r = stackr(s)
746  s = s - 1
747 
748 ! KEEP SPLITTING A(L), ... , A(R) UNTIL L >= R.
749 
750  20 CONTINUE
751  i = l
752  j = r
753  k = (l+r) / 2
754  x = a(k)
755 
756 ! REPEAT UNTIL I > J.
757 
758  DO
759  DO
760  IF (a(i).LT.x) THEN ! Search from lower end
761  i = i + 1
762  cycle
763  ELSE
764  EXIT
765  END IF
766  END DO
767 
768  DO
769  IF (x.LT.a(j)) THEN ! Search from upper end
770  j = j - 1
771  cycle
772  ELSE
773  EXIT
774  END IF
775  END DO
776 
777  IF (i.LE.j) THEN ! Swap positions i & j
778  w = a(i)
779  a(i) = a(j)
780  a(j) = w
781  i = i + 1
782  j = j - 1
783  IF (i.GT.j) EXIT
784  ELSE
785  EXIT
786  END IF
787  END DO
788 
789  IF (j-l.GE.r-i) THEN
790  IF (l.LT.j) THEN
791  s = s + 1
792  stackl(s) = l
793  stackr(s) = j
794  END IF
795  l = i
796  ELSE
797  IF (i.LT.r) THEN
798  s = s + 1
799  stackl(s) = i
800  stackr(s) = r
801  END IF
802  r = j
803  END IF
804 
805  IF (l.LT.r) go to 20
806  IF (s.NE.0) go to 10
807 
808  RETURN
809 
810  END SUBROUTINE quicksortrfreal
811 
812 
813 
814 
815 
816 ! ******************************************************************************
817 !
818 ! Purpose: Sort elements of double-precision array a of size n into ascending
819 ! order and sort b along with it.
820 !
821 ! Description: Uses quicksort method.
822 !
823 ! Input:
824 ! a Array containing unsorted elements
825 ! b Integer array
826 ! n Number of elements in array a
827 !
828 ! Output:
829 ! a Array containing sorted elements
830 ! b Integer array containing elements in same sorted order as a
831 !
832 ! Notes:
833 ! 1. Taken from WWW, cannot remember where... Seems to originate from
834 ! Nicklaus Wirths book, see remark below.
835 ! 2. No modifications to original, apart from a few cosmetic changes and
836 ! from deletion of second array which was also being sorted along with a.
837 !
838 ! ******************************************************************************
839 
840  SUBROUTINE quicksortrfrealinteger(a,b,n)
841 
842 ! NON-RECURSIVE STACK VERSION OF QUICKSORT FROM N.WIRTHS PASCAL
843 ! BOOK, 'ALGORITHMS + DATA STRUCTURES = PROGRAMS'.
844 
845  IMPLICIT NONE
846 
847  INTEGER, INTENT(IN) :: n
848  INTEGER, INTENT(INOUT) :: b(n)
849  REAL(KIND=RFREAL), INTENT(INOUT) :: a(n)
850 
851 ! Local Variables
852 
853  INTEGER :: i, j, k, l, r, s, stackl(50), stackr(50), v
854  REAL(KIND=RFREAL) :: w, x
855 
856  s = 1
857  stackl(1) = 1
858  stackr(1) = n
859 
860 ! KEEP TAKING THE TOP REQUEST FROM THE STACK UNTIL S = 0.
861 
862  10 CONTINUE
863  l = stackl(s)
864  r = stackr(s)
865  s = s - 1
866 
867 ! KEEP SPLITTING A(L), ... , A(R) UNTIL L >= R.
868 
869  20 CONTINUE
870  i = l
871  j = r
872  k = (l+r) / 2
873  x = a(k)
874 
875 ! REPEAT UNTIL I > J.
876 
877  DO
878  DO
879  IF (a(i).LT.x) THEN ! Search from lower end
880  i = i + 1
881  cycle
882  ELSE
883  EXIT
884  END IF
885  END DO
886 
887  DO
888  IF (x.LT.a(j)) THEN ! Search from upper end
889  j = j - 1
890  cycle
891  ELSE
892  EXIT
893  END IF
894  END DO
895 
896  IF (i.LE.j) THEN ! Swap positions i & j
897  w = a(i)
898  a(i) = a(j)
899  a(j) = w
900  v = b(i)
901  b(i) = b(j)
902  b(j) = v
903  i = i + 1
904  j = j - 1
905  IF (i.GT.j) EXIT
906  ELSE
907  EXIT
908  END IF
909  END DO
910 
911  IF (j-l.GE.r-i) THEN
912  IF (l.LT.j) THEN
913  s = s + 1
914  stackl(s) = l
915  stackr(s) = j
916  END IF
917  l = i
918  ELSE
919  IF (i.LT.r) THEN
920  s = s + 1
921  stackl(s) = i
922  stackr(s) = r
923  END IF
924  r = j
925  END IF
926 
927  IF (l.LT.r) go to 20
928  IF (s.NE.0) go to 10
929 
930  RETURN
931 
932  END SUBROUTINE quicksortrfrealinteger
933 
934 
935 
936 
937 
938 
939 
940 ! ******************************************************************************
941 !
942 ! Purpose: Remove duplicated elements of sorted integer arrays a of size na.
943 !
944 ! Description: None.
945 !
946 ! Input:
947 ! a Array
948 ! na Number of elements in array a
949 ! b Array, must be sorted in increasing order
950 ! nb Number of elements in array b
951 !
952 ! Output:
953 ! b Array without elements shared with a
954 ! nb2 Number of elements in array b which are not shared with a
955 !
956 ! Notes:
957 ! 1. List b must be sorted in increasing order on entry.
958 !
959 ! ******************************************************************************
960 
961  SUBROUTINE removecommonsortedintegers(a,na,b,nb,nb2)
962 
963  IMPLICIT NONE
964 
965 ! ******************************************************************************
966 ! Declarations and definitions
967 ! ******************************************************************************
968 
969 ! ==============================================================================
970 ! Parameters
971 ! ==============================================================================
972 
973  INTEGER, INTENT(IN) :: na
974  INTEGER, INTENT(IN) :: nb
975  INTEGER, INTENT(OUT) :: nb2
976  INTEGER, INTENT(IN) :: a(na)
977  INTEGER, INTENT(INOUT) :: b(nb)
978 
979 ! ==============================================================================
980 ! Locals
981 ! ==============================================================================
982 
983  INTEGER :: ia,ib2,iloc
984 
985 ! ******************************************************************************
986 ! Start
987 ! ******************************************************************************
988 
989  nb2 = nb
990 
991  DO ia = 1,na
992  CALL binarysearchinteger(b(1:nb2),nb2,a(ia),iloc)
993 
994  IF ( iloc /= element_not_found ) THEN
995  CALL removeinteger(b,nb2,iloc)
996  END IF ! iLoc
997  END DO ! ia
998 
999  END SUBROUTINE removecommonsortedintegers
1000 
1001 
1002 
1003 
1004 
1005 
1006 ! ******************************************************************************
1007 !
1008 ! Purpose: Remove duplicated elements of sorted integer arrays a and b and
1009 ! store in array c, while keeping non-duplicated elements in original arrays.
1010 !
1011 ! Description: None.
1012 !
1013 ! Input:
1014 ! a Array
1015 ! na Number of elements in array a
1016 ! b Array, must be sorted in increasing order
1017 ! nb Number of elements in array b
1018 ! c Array
1019 ! ncMax Size of array c
1020 !
1021 ! Output:
1022 ! a Array a without duplicated elements
1023 ! na2 Number of elements in array a
1024 ! b Array b without duplicated elements
1025 ! nb2 Number of elements in array b
1026 ! c Array c with duplicated elements on a and b
1027 ! nc Number of elements in array c
1028 ! errorFlag Error flag indicating whether routine completed successfully.
1029 ! Any non-zero value indicates failure.
1030 !
1031 ! Notes:
1032 ! 1. List b must be sorted in increasing order on entry. List a, strictly
1033 ! speaking must not be sorted. If a is not sorted, then the array c will
1034 ! not be sorted either.
1035 !
1036 ! ******************************************************************************
1037 
1038  SUBROUTINE removecommonsortedintegersfancy(a,na,na2,b,nb,nb2,c,ncMax,nc, &
1039  errorflag)
1040 
1041  IMPLICIT NONE
1042 
1043 ! ******************************************************************************
1044 ! Declarations and definitions
1045 ! ******************************************************************************
1046 
1047 ! ==============================================================================
1048 ! Parameters
1049 ! ==============================================================================
1050 
1051  INTEGER, INTENT(IN) :: na,nb,ncmax
1052  INTEGER, INTENT(OUT) :: errorflag,na2,nb2,nc
1053  INTEGER, INTENT(INOUT) :: a(na),b(nb)
1054  INTEGER, INTENT(OUT) :: c(ncmax)
1055 
1056 ! ==============================================================================
1057 ! Locals
1058 ! ==============================================================================
1059 
1060  INTEGER :: ia,ib2,iloc
1061 
1062 ! ******************************************************************************
1063 ! Start
1064 ! ******************************************************************************
1065 
1066  errorflag = err_none
1067 
1068  na2 = na
1069  nb2 = nb
1070  nc = 0
1071 
1072  ia = 1
1073 
1074  emptyloop: DO
1075  IF ( nb2 > 1 ) THEN
1076  CALL binarysearchinteger(b(1:nb2),nb2,a(ia),iloc)
1077  ELSE
1078  IF ( b(1) == a(ia) ) THEN
1079  iloc = element_not_found + 1 ! Set to anything but ELEMENT_NOT_FOUND
1080  ELSE
1081  iloc = element_not_found
1082  END IF ! b(1)
1083  END IF ! nb
1084 
1085  IF ( iloc /= element_not_found ) THEN
1086  nc = nc + 1
1087 
1088  IF ( nc > ncmax ) THEN
1089  errorflag = err_none - 1 ! Set to anything but ERR_NONE
1090  EXIT emptyloop
1091  END IF ! ic
1092 
1093  c(nc) = a(ia)
1094 
1095  CALL removeinteger(a(1:na2),na2,ia)
1096  CALL removeinteger(b(1:nb2),nb2,iloc)
1097  ELSE
1098  ia = ia + 1
1099  END IF ! iLoc
1100 
1101  IF ( ia > na2 ) THEN
1102  EXIT emptyloop
1103  END IF ! ia
1104  END DO emptyloop
1105 
1106  END SUBROUTINE removecommonsortedintegersfancy
1107 
1108 
1109 
1110 
1111 
1112 ! ******************************************************************************
1113 !
1114 ! Purpose: Remove entry from integer array and set last element to crazy value.
1115 !
1116 ! Description: None.
1117 !
1118 ! Input:
1119 ! a Array
1120 ! na Number of elements in array a
1121 ! iLoc Position of entry in array a to be removed
1122 !
1123 ! Output:
1124 ! a Array with iLoc-th element removed
1125 ! na Number of elements in array a after removing iLoc-th element
1126 !
1127 ! Notes: None.
1128 !
1129 ! ******************************************************************************
1130 
1131  SUBROUTINE removeinteger(a,na,iLoc)
1132 
1133  IMPLICIT NONE
1134 
1135 ! ******************************************************************************
1136 ! Declarations and definitions
1137 ! ******************************************************************************
1138 
1139 ! ==============================================================================
1140 ! Parameters
1141 ! ==============================================================================
1142 
1143  INTEGER, INTENT(IN) :: iloc
1144  INTEGER, INTENT(INOUT) :: na
1145  INTEGER, INTENT(INOUT) :: a(:)
1146 
1147 ! ==============================================================================
1148 ! Locals
1149 ! ==============================================================================
1150 
1151  INTEGER :: ia
1152 
1153 ! ******************************************************************************
1154 ! Start
1155 ! ******************************************************************************
1156 
1157  DO ia = iloc,na-1
1158  a(ia) = a(ia+1)
1159  END DO ! ia
1160 
1161  a(na) = crazy_value_int
1162 
1163  na = na - 1
1164 
1165 ! ******************************************************************************
1166 ! End
1167 ! ******************************************************************************
1168 
1169  END SUBROUTINE removeinteger
1170 
1171 
1172 
1173 
1174 
1175 
1176 
1177 
1178 
1179 ! ******************************************************************************
1180 !
1181 ! Purpose: Delete duplicated elements of sorted integer arrays a of size na.
1182 !
1183 ! Description: None.
1184 !
1185 ! Input:
1186 ! a Array containing sorted elements, possibly containing duplicates
1187 ! na Number of elements in array a
1188 !
1189 ! Output:
1190 ! a Array containing sorted elements without duplicates
1191 ! nb Number of elements in sorted array a
1192 !
1193 ! Notes: None.
1194 !
1195 ! ******************************************************************************
1196 
1197  SUBROUTINE simplifysortedintegers(a,na,nb)
1198 
1199  IMPLICIT NONE
1200 
1201 ! ******************************************************************************
1202 ! Declarations and definitions
1203 ! ******************************************************************************
1204 
1205 ! ==============================================================================
1206 ! Parameters
1207 ! ==============================================================================
1208 
1209  INTEGER, INTENT(IN) :: na
1210  INTEGER, INTENT(INOUT) :: a(na)
1211  INTEGER, INTENT(OUT) :: nb
1212 
1213 ! ==============================================================================
1214 ! Locals
1215 ! ==============================================================================
1216 
1217  INTEGER :: ia,im
1218  INTEGER :: m(na)
1219 
1220 ! ******************************************************************************
1221 ! Start
1222 ! ******************************************************************************
1223 
1224  nb = 0
1225  m(:) = 0
1226  m(1) = a(1)
1227  im = 1
1228 
1229  DO ia = 2,na
1230  IF ( a(ia) /= a(ia-1) ) THEN
1231  im = im + 1
1232  m(im) = a(ia)
1233  END IF ! a
1234  END DO ! ia
1235 
1236  nb = im
1237 
1238  a(1:im) = m(1:im)
1239  a(im+1:na) = 0
1240 
1241  END SUBROUTINE simplifysortedintegers
1242 
1243 
1244 
1245 
1246 ! ******************************************************************************
1247 ! End
1248 ! ******************************************************************************
1249 
1250 END MODULE modsortsearch
1251 
1252 
1253 ! ******************************************************************************
1254 !
1255 ! RCS Revision history:
1256 !
1257 ! $Log: ModSortSearch.F90,v $
1258 ! Revision 1.18 2008/12/06 08:44:19 mtcampbe
1259 ! Updated license.
1260 !
1261 ! Revision 1.17 2008/11/19 22:17:30 mtcampbe
1262 ! Added Illinois Open Source License/Copyright
1263 !
1264 ! Revision 1.16 2006/04/07 15:19:18 haselbac
1265 ! Removed tabs
1266 !
1267 ! Revision 1.15 2006/03/20 13:52:56 haselbac
1268 ! Added new routine, some clean-up
1269 !
1270 ! Revision 1.14 2005/06/20 17:06:16 haselbac
1271 ! New routine to rm common ints from lists, put routines in proper order
1272 !
1273 ! Revision 1.13 2005/05/17 01:12:36 haselbac
1274 ! Improved description of BinarySearchInteger, cosmetics
1275 !
1276 ! Revision 1.12 2005/04/21 01:20:03 haselbac
1277 ! Bug fix in binary search; extended to return info if failed
1278 !
1279 ! Revision 1.11 2004/12/29 21:03:52 haselbac
1280 ! Added new procedure, cosmetics
1281 !
1282 ! Revision 1.10 2004/01/22 16:02:41 haselbac
1283 ! Changed declaration to eliminate warning on ALC
1284 !
1285 ! Revision 1.9 2003/12/04 03:28:28 haselbac
1286 ! Added routine QuickSortIntegerInteger
1287 !
1288 ! Revision 1.8 2003/11/25 21:03:14 haselbac
1289 ! Fixed bug in MergeSortedIntegers: Was accessing m(0)
1290 !
1291 ! Revision 1.7 2003/08/19 22:46:55 haselbac
1292 ! Added CycleList routine
1293 !
1294 ! Revision 1.6 2003/07/22 02:02:19 haselbac
1295 ! Fixed bug in merging of sorted lists
1296 !
1297 ! Revision 1.5 2003/03/15 17:51:38 haselbac
1298 ! Added routine to simplify sorted list of integers
1299 !
1300 ! Revision 1.4 2003/01/28 16:47:51 haselbac
1301 ! Bug fix in MergeSortedIntegers
1302 !
1303 ! Revision 1.3 2002/09/09 15:00:14 haselbac
1304 ! Removed some error checking, changed interface to MergeSortedIntegers
1305 !
1306 ! Revision 1.2 2002/04/11 18:55:04 haselbac
1307 ! Added routine to sort integer array based on real key
1308 !
1309 ! Revision 1.1 2002/03/01 17:04:24 haselbac
1310 ! Initial revision
1311 !
1312 ! ******************************************************************************
1313 
1314 
1315 
1316 
1317 
1318 
subroutine findcommonsortedintegers(a, na, b, nb, c, ncMax, nc, errorFlag)
unsigned char r() const
Definition: Color.h:68
FT m(int i, int j) const
subroutine removeinteger(a, na, iLoc)
j indices k indices k
Definition: Indexing.h:6
double s
Definition: blastest.C:80
unsigned char b() const
Definition: Color.h:70
subroutine cyclelist(a, na, i, v)
subroutine simplifysortedintegers(a, na, nb)
subroutine quicksortinteger(a, n)
RT c() const
Definition: Line_2.h:150
subroutine binarysearchinteger(a, n, v, i, j)
*********************************************************************Illinois Open Source License ****University of Illinois NCSA **Open Source License University of Illinois All rights reserved ****Developed free of to any person **obtaining a copy of this software and associated documentation to deal with the Software without including without limitation the rights to and or **sell copies of the and to permit persons to whom the **Software is furnished to do subject to the following this list of conditions and the following disclaimers ****Redistributions in binary form must reproduce the above **copyright this list of conditions and the following **disclaimers in the documentation and or other materials **provided with the distribution ****Neither the names of the Center for Simulation of Advanced the University of nor the names of its **contributors may be used to endorse or promote products derived **from this Software without specific prior written permission ****THE SOFTWARE IS PROVIDED AS WITHOUT WARRANTY OF ANY **EXPRESS OR INCLUDING BUT NOT LIMITED TO THE WARRANTIES **OF FITNESS FOR A PARTICULAR PURPOSE AND **NONINFRINGEMENT IN NO EVENT SHALL THE CONTRIBUTORS OR **COPYRIGHT HOLDERS BE LIABLE FOR ANY DAMAGES OR OTHER WHETHER IN AN ACTION OF TORT OR **ARISING OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE **USE OR OTHER DEALINGS WITH THE SOFTWARE v
Definition: roccomf90.h:20
subroutine removecommonsortedintegersfancy(a, na, na2, b, nb, nb2, c, ncMax, nc, errorFlag)
subroutine quicksortintegerinteger(a, b, n)
blockLoc i
Definition: read.cpp:79
void int int REAL * x
Definition: read.cpp:74
const NT & n
subroutine quicksortrfreal(a, n)
subroutine quicksortrfrealinteger(a, b, n)
j indices j
Definition: Indexing.h:6
subroutine removecommonsortedintegers(a, na, b, nb, nb2)
subroutine mergesortedintegers(global, na, nb, a, b, nm, im, m)
subroutine errorstop(global, errorCode, errorLine, addMessage)
Definition: ModError.F90:483
RT a() const
Definition: Line_2.h:140