m_IndexBin_integer.F90 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  3. !-----------------------------------------------------------------------
  4. ! CVS m_IndexBin_integer.F90,v 1.3 2004-04-21 22:54:45 jacob Exp
  5. ! CVS MCT_2_8_0
  6. !BOP -------------------------------------------------------------------
  7. !
  8. ! !MODULE: m_IndexBin_integer - Template of indexed bin-sorting module
  9. !
  10. ! !DESCRIPTION:
  11. !
  12. ! !INTERFACE:
  13. module m_IndexBin_integer
  14. implicit none
  15. private ! except
  16. public :: IndexBin
  17. interface IndexBin; module procedure &
  18. IndexBin0_, &
  19. IndexBin1_, &
  20. IndexBin1w_
  21. end interface
  22. ! !REVISION HISTORY:
  23. ! 17Feb99 - Jing Guo <guo@thunder> - initial prototype/prolog/code
  24. !EOP ___________________________________________________________________
  25. character(len=*),parameter :: myname='MCT(MPEU)::m_IndexBin_integer'
  26. contains
  27. !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  28. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  29. !BOP -------------------------------------------------------------------
  30. !
  31. ! !IROUTINE: IndexBin0_ - Indexed sorting for a single value
  32. !
  33. ! !DESCRIPTION:
  34. !
  35. ! !INTERFACE:
  36. subroutine IndexBin0_(n,indx,keys,key0,ln0)
  37. use m_stdio, only : stderr
  38. use m_die, only : die
  39. implicit none
  40. integer, intent(in) :: n
  41. integer, dimension(n), intent(inout) :: indx
  42. integer, dimension(n), intent(in) :: keys
  43. integer, intent(in) :: key0 ! The key value to be moved to front
  44. integer,optional,intent(out) :: ln0
  45. ! !REVISION HISTORY:
  46. ! 16Feb99 - Jing Guo <guo@thunder> - initial prototype/prolog/code
  47. ! 27Sep99 - Jing Guo <guo@thunder> - Fixed a bug pointed out by
  48. ! Chris Redder
  49. !EOP ___________________________________________________________________
  50. character(len=*),parameter :: myname_=myname//'::IndexBin0_'
  51. integer,allocatable,dimension(:) :: inew
  52. integer :: ni,ix,i,ier
  53. integer :: ln(0:1),lc(0:1)
  54. !________________________________________
  55. allocate(inew(n),stat=ier)
  56. if(ier /= 0) then
  57. write(stderr,'(2a,i4)') myname_, &
  58. ': allocate() error, stat =',ier
  59. call die(myname_)
  60. endif
  61. !________________________________________
  62. ! Count numbers entries for the given key0
  63. lc(0)=1 ! the location of values the same as key0
  64. ln(0)=0
  65. do i=1,n
  66. if(keys(i) == key0) ln(0)=ln(0)+1
  67. end do
  68. lc(1)=ln(0)+1 ! the location of values not the same as key0
  69. !________________________________________
  70. ! Reset the counters
  71. ln(0:1)=0
  72. do i=1,n
  73. ix=indx(i)
  74. if(keys(ix) == key0) then
  75. ni=lc(0)+ln(0)
  76. ln(0)=ln(0)+1
  77. else
  78. ni=lc(1)+ln(1)
  79. ln(1)=ln(1)+1
  80. endif
  81. inew(ni)=ix
  82. end do
  83. !________________________________________
  84. ! Sort out the old pointers according to the new order
  85. indx(:)=inew(:)
  86. if(present(ln0)) ln0=ln(0)
  87. !________________________________________
  88. deallocate(inew)
  89. end subroutine IndexBin0_
  90. !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  91. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  92. !BOP -------------------------------------------------------------------
  93. !
  94. ! !IROUTINE: IndexBin1_ - Indexed sorting into a set of given bins
  95. !
  96. ! !DESCRIPTION:
  97. !
  98. ! !INTERFACE:
  99. subroutine IndexBin1_(n,indx,keys,bins,lcs,lns)
  100. use m_stdio, only : stderr
  101. use m_die, only : die
  102. implicit none
  103. integer, intent(in) :: n
  104. integer, dimension(n),intent(inout) :: indx
  105. integer, dimension(n),intent(in) :: keys
  106. integer, dimension(:),intent(in) :: bins! values of the bins
  107. integer, dimension(:),intent(out) :: lcs ! locs. of the bins
  108. integer, dimension(:),intent(out) :: lns ! sizes of the bins
  109. ! !REVISION HISTORY:
  110. ! 16Feb99 - Jing Guo <guo@thunder> - initial prototype/prolog/code
  111. !EOP ___________________________________________________________________
  112. character(len=*),parameter :: myname_=myname//'::IndexBin1_'
  113. integer,allocatable,dimension(:) :: ibin,inew
  114. integer :: nbin,lc0,ln0
  115. integer :: ni,ix,ib,i,ier
  116. !________________________________________
  117. nbin=size(bins)
  118. if(nbin==0) return
  119. !________________________________________
  120. allocate(ibin(n),inew(n),stat=ier)
  121. if(ier /= 0) then
  122. write(stderr,'(2a,i4)') myname_, &
  123. ': allocate() error, stat =',ier
  124. call die(myname_)
  125. endif
  126. !________________________________________
  127. do ib=1,nbin
  128. lns(ib)=0
  129. lcs(ib)=0
  130. end do
  131. !________________________________________
  132. ! Count numbers in every bin, and store the bin-ID for
  133. ! later use.
  134. do i=1,n
  135. ix=indx(i)
  136. call search_(keys(ix),nbin,bins,ib) ! ib = 1:nbin; =0 if not found
  137. ibin(i)=ib
  138. if(ib /= 0) lns(ib)=lns(ib)+1
  139. end do
  140. !________________________________________
  141. ! Count the locations of every bin.
  142. lc0=1
  143. do ib=1,nbin
  144. lcs(ib)=lc0
  145. lc0=lc0+lns(ib)
  146. end do
  147. !________________________________________
  148. ! Reset the counters
  149. ln0=0
  150. lns(1:nbin)=0
  151. do i=1,n
  152. ib=ibin(i) ! the bin-index of keys(indx(i))
  153. if(ib/=0) then
  154. ni=lcs(ib)+lns(ib)
  155. lns(ib)=lns(ib)+1
  156. else
  157. ni=lc0+ln0
  158. ln0=ln0+1
  159. endif
  160. inew(ni)=indx(i) ! the current value is put in the new order
  161. end do
  162. !________________________________________
  163. ! Sort out the old pointers according to the new order
  164. indx(:)=inew(:)
  165. !________________________________________
  166. deallocate(ibin,inew)
  167. contains
  168. subroutine search_(key,nbin,bins,ib)
  169. implicit none
  170. integer, intent(in) :: key
  171. integer,intent(in) :: nbin
  172. integer, intent(in),dimension(:) :: bins
  173. integer,intent(out) :: ib
  174. integer :: i
  175. ib=0
  176. do i=1,nbin
  177. if(key==bins(i)) then
  178. ib=i
  179. return
  180. endif
  181. end do
  182. end subroutine search_
  183. end subroutine IndexBin1_
  184. !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  185. ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS !
  186. !BOP -------------------------------------------------------------------
  187. !
  188. ! !IROUTINE: IndexBin1w_ - IndexBin1_ wrapped without working arrays
  189. !
  190. ! !DESCRIPTION:
  191. !
  192. ! !INTERFACE:
  193. subroutine IndexBin1w_(n,indx,keys,bins)
  194. use m_stdio, only : stderr
  195. use m_die, only : die
  196. implicit none
  197. integer, intent(in) :: n
  198. integer,dimension(n),intent(inout) :: indx
  199. integer,dimension(n),intent(in) :: keys
  200. integer,dimension(:),intent(in) :: bins ! values of the bins
  201. ! !REVISION HISTORY:
  202. ! 17Feb99 - Jing Guo <guo@thunder> - initial prototype/prolog/code
  203. !EOP ___________________________________________________________________
  204. character(len=*),parameter :: myname_=myname//'::IndexBin1w_'
  205. integer :: ier
  206. integer,dimension(:),allocatable :: lcs,lns
  207. integer :: nbin
  208. nbin=size(bins)
  209. if(nbin==0) return
  210. allocate(lcs(nbin),lns(nbin),stat=ier)
  211. if(ier /= 0) then
  212. write(stderr,'(2a,i4)') myname_,': allocate() error, stat =',ier
  213. call die(myname_)
  214. endif
  215. call IndexBin1_(n,indx,keys,bins,lcs,lns)
  216. deallocate(lcs,lns)
  217. end subroutine IndexBin1w_
  218. end module m_IndexBin_integer