dsort.f 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. *DECK DSORT
  2. SUBROUTINE DSORT (DX, DY, N, KFLAG)
  3. C***BEGIN PROLOGUE DSORT
  4. C***PURPOSE Sort an array and optionally make the same interchanges in
  5. C an auxiliary array. The array may be sorted in increasing
  6. C or decreasing order. A slightly modified QUICKSORT
  7. C algorithm is used.
  8. C***LIBRARY SLATEC
  9. C***CATEGORY N6A2B
  10. C***TYPE DOUBLE PRECISION (SSORT-S, DSORT-D, ISORT-I)
  11. C***KEYWORDS SINGLETON QUICKSORT, SORT, SORTING
  12. C***AUTHOR Jones, R. E., (SNLA)
  13. C Wisniewski, J. A., (SNLA)
  14. C***DESCRIPTION
  15. C
  16. C DSORT sorts array DX and optionally makes the same interchanges in
  17. C array DY. The array DX may be sorted in increasing order or
  18. C decreasing order. A slightly modified quicksort algorithm is used.
  19. C
  20. C Description of Parameters
  21. C DX - array of values to be sorted (usually abscissas)
  22. C DY - array to be (optionally) carried along
  23. C N - number of values in array DX to be sorted
  24. C KFLAG - control parameter
  25. C = 2 means sort DX in increasing order and carry DY along.
  26. C = 1 means sort DX in increasing order (ignoring DY)
  27. C = -1 means sort DX in decreasing order (ignoring DY)
  28. C = -2 means sort DX in decreasing order and carry DY along.
  29. C
  30. C***REFERENCES R. C. Singleton, Algorithm 347, An efficient algorithm
  31. C for sorting with minimal storage, Communications of
  32. C the ACM, 12, 3 (1969), pp. 185-187.
  33. C***ROUTINES CALLED XERMSG
  34. C***REVISION HISTORY (YYMMDD)
  35. C 761101 DATE WRITTEN
  36. C 761118 Modified to use the Singleton quicksort algorithm. (JAW)
  37. C 890531 Changed all specific intrinsics to generic. (WRB)
  38. C 890831 Modified array declarations. (WRB)
  39. C 891009 Removed unreferenced statement labels. (WRB)
  40. C 891024 Changed category. (WRB)
  41. C 891024 REVISION DATE from Version 3.2
  42. C 891214 Prologue converted to Version 4.0 format. (BAB)
  43. C 900315 CALLs to XERROR changed to CALLs to XERMSG. (THJ)
  44. C 901012 Declared all variables; changed X,Y to DX,DY; changed
  45. C code to parallel SSORT. (M. McClain)
  46. C 920501 Reformatted the REFERENCES section. (DWL, WRB)
  47. C 920519 Clarified error messages. (DWL)
  48. C 920801 Declarations section rebuilt and code restructured to use
  49. C IF-THEN-ELSE-ENDIF. (RWC, WRB)
  50. C***END PROLOGUE DSORT
  51. C .. Scalar Arguments ..
  52. INTEGER KFLAG, N
  53. C .. Array Arguments ..
  54. DOUBLE PRECISION DX(*), DY(*)
  55. C .. Local Scalars ..
  56. DOUBLE PRECISION R, T, TT, TTY, TY
  57. INTEGER I, IJ, J, K, KK, L, M, NN
  58. C .. Local Arrays ..
  59. INTEGER IL(21), IU(21)
  60. C .. External Subroutines ..
  61. EXTERNAL XERMSG
  62. C .. Intrinsic Functions ..
  63. INTRINSIC ABS, INT
  64. C***FIRST EXECUTABLE STATEMENT DSORT
  65. NN = N
  66. IF (NN .LT. 1) THEN
  67. CALL XERMSG ('SLATEC', 'DSORT',
  68. + 'The number of values to be sorted is not positive.', 1, 1)
  69. RETURN
  70. ENDIF
  71. C
  72. KK = ABS(KFLAG)
  73. IF (KK.NE.1 .AND. KK.NE.2) THEN
  74. CALL XERMSG ('SLATEC', 'DSORT',
  75. + 'The sort control parameter, K, is not 2, 1, -1, or -2.', 2,
  76. + 1)
  77. RETURN
  78. ENDIF
  79. C
  80. C Alter array DX to get decreasing order if needed
  81. C
  82. IF (KFLAG .LE. -1) THEN
  83. DO 10 I=1,NN
  84. DX(I) = -DX(I)
  85. 10 CONTINUE
  86. ENDIF
  87. C
  88. IF (KK .EQ. 2) GO TO 100
  89. C
  90. C Sort DX only
  91. C
  92. M = 1
  93. I = 1
  94. J = NN
  95. R = 0.375D0
  96. C
  97. 20 IF (I .EQ. J) GO TO 60
  98. IF (R .LE. 0.5898437D0) THEN
  99. R = R+3.90625D-2
  100. ELSE
  101. R = R-0.21875D0
  102. ENDIF
  103. C
  104. 30 K = I
  105. C
  106. C Select a central element of the array and save it in location T
  107. C
  108. IJ = I + INT((J-I)*R)
  109. T = DX(IJ)
  110. C
  111. C If first element of array is greater than T, interchange with T
  112. C
  113. IF (DX(I) .GT. T) THEN
  114. DX(IJ) = DX(I)
  115. DX(I) = T
  116. T = DX(IJ)
  117. ENDIF
  118. L = J
  119. C
  120. C If last element of array is less than than T, interchange with T
  121. C
  122. IF (DX(J) .LT. T) THEN
  123. DX(IJ) = DX(J)
  124. DX(J) = T
  125. T = DX(IJ)
  126. C
  127. C If first element of array is greater than T, interchange with T
  128. C
  129. IF (DX(I) .GT. T) THEN
  130. DX(IJ) = DX(I)
  131. DX(I) = T
  132. T = DX(IJ)
  133. ENDIF
  134. ENDIF
  135. C
  136. C Find an element in the second half of the array which is smaller
  137. C than T
  138. C
  139. 40 L = L-1
  140. IF (DX(L) .GT. T) GO TO 40
  141. C
  142. C Find an element in the first half of the array which is greater
  143. C than T
  144. C
  145. 50 K = K+1
  146. IF (DX(K) .LT. T) GO TO 50
  147. C
  148. C Interchange these elements
  149. C
  150. IF (K .LE. L) THEN
  151. TT = DX(L)
  152. DX(L) = DX(K)
  153. DX(K) = TT
  154. GO TO 40
  155. ENDIF
  156. C
  157. C Save upper and lower subscripts of the array yet to be sorted
  158. C
  159. IF (L-I .GT. J-K) THEN
  160. IL(M) = I
  161. IU(M) = L
  162. I = K
  163. M = M+1
  164. ELSE
  165. IL(M) = K
  166. IU(M) = J
  167. J = L
  168. M = M+1
  169. ENDIF
  170. GO TO 70
  171. C
  172. C Begin again on another portion of the unsorted array
  173. C
  174. 60 M = M-1
  175. IF (M .EQ. 0) GO TO 190
  176. I = IL(M)
  177. J = IU(M)
  178. C
  179. 70 IF (J-I .GE. 1) GO TO 30
  180. IF (I .EQ. 1) GO TO 20
  181. I = I-1
  182. C
  183. 80 I = I+1
  184. IF (I .EQ. J) GO TO 60
  185. T = DX(I+1)
  186. IF (DX(I) .LE. T) GO TO 80
  187. K = I
  188. C
  189. 90 DX(K+1) = DX(K)
  190. K = K-1
  191. IF (T .LT. DX(K)) GO TO 90
  192. DX(K+1) = T
  193. GO TO 80
  194. C
  195. C Sort DX and carry DY along
  196. C
  197. 100 M = 1
  198. I = 1
  199. J = NN
  200. R = 0.375D0
  201. C
  202. 110 IF (I .EQ. J) GO TO 150
  203. IF (R .LE. 0.5898437D0) THEN
  204. R = R+3.90625D-2
  205. ELSE
  206. R = R-0.21875D0
  207. ENDIF
  208. C
  209. 120 K = I
  210. C
  211. C Select a central element of the array and save it in location T
  212. C
  213. IJ = I + INT((J-I)*R)
  214. T = DX(IJ)
  215. TY = DY(IJ)
  216. C
  217. C If first element of array is greater than T, interchange with T
  218. C
  219. IF (DX(I) .GT. T) THEN
  220. DX(IJ) = DX(I)
  221. DX(I) = T
  222. T = DX(IJ)
  223. DY(IJ) = DY(I)
  224. DY(I) = TY
  225. TY = DY(IJ)
  226. ENDIF
  227. L = J
  228. C
  229. C If last element of array is less than T, interchange with T
  230. C
  231. IF (DX(J) .LT. T) THEN
  232. DX(IJ) = DX(J)
  233. DX(J) = T
  234. T = DX(IJ)
  235. DY(IJ) = DY(J)
  236. DY(J) = TY
  237. TY = DY(IJ)
  238. C
  239. C If first element of array is greater than T, interchange with T
  240. C
  241. IF (DX(I) .GT. T) THEN
  242. DX(IJ) = DX(I)
  243. DX(I) = T
  244. T = DX(IJ)
  245. DY(IJ) = DY(I)
  246. DY(I) = TY
  247. TY = DY(IJ)
  248. ENDIF
  249. ENDIF
  250. C
  251. C Find an element in the second half of the array which is smaller
  252. C than T
  253. C
  254. 130 L = L-1
  255. IF (DX(L) .GT. T) GO TO 130
  256. C
  257. C Find an element in the first half of the array which is greater
  258. C than T
  259. C
  260. 140 K = K+1
  261. IF (DX(K) .LT. T) GO TO 140
  262. C
  263. C Interchange these elements
  264. C
  265. IF (K .LE. L) THEN
  266. TT = DX(L)
  267. DX(L) = DX(K)
  268. DX(K) = TT
  269. TTY = DY(L)
  270. DY(L) = DY(K)
  271. DY(K) = TTY
  272. GO TO 130
  273. ENDIF
  274. C
  275. C Save upper and lower subscripts of the array yet to be sorted
  276. C
  277. IF (L-I .GT. J-K) THEN
  278. IL(M) = I
  279. IU(M) = L
  280. I = K
  281. M = M+1
  282. ELSE
  283. IL(M) = K
  284. IU(M) = J
  285. J = L
  286. M = M+1
  287. ENDIF
  288. GO TO 160
  289. C
  290. C Begin again on another portion of the unsorted array
  291. C
  292. 150 M = M-1
  293. IF (M .EQ. 0) GO TO 190
  294. I = IL(M)
  295. J = IU(M)
  296. C
  297. 160 IF (J-I .GE. 1) GO TO 120
  298. IF (I .EQ. 1) GO TO 110
  299. I = I-1
  300. C
  301. 170 I = I+1
  302. IF (I .EQ. J) GO TO 150
  303. T = DX(I+1)
  304. TY = DY(I+1)
  305. IF (DX(I) .LE. T) GO TO 170
  306. K = I
  307. C
  308. 180 DX(K+1) = DX(K)
  309. DY(K+1) = DY(K)
  310. K = K-1
  311. IF (T .LT. DX(K)) GO TO 180
  312. DX(K+1) = T
  313. DY(K+1) = TY
  314. GO TO 170
  315. C
  316. C Clean up
  317. C
  318. 190 IF (KFLAG .LE. -1) THEN
  319. DO 200 I=1,NN
  320. DX(I) = -DX(I)
  321. 200 CONTINUE
  322. ENDIF
  323. RETURN
  324. END