[cig-commits] [commit] devel, master: Replace bubble sort with heap sort. (968b09a)

cig_noreply at geodynamics.org cig_noreply at geodynamics.org
Thu Nov 6 08:20:37 PST 2014


Repository : https://github.com/geodynamics/specfem3d_globe

On branches: devel,master
Link       : https://github.com/geodynamics/specfem3d_globe/compare/bc58e579b3b0838a0968725a076f5904845437ca...be63f20cbb6f462104e949894dbe205d2398cd7f

>---------------------------------------------------------------

commit 968b09ad64560cfe4362140719ce5aca0036288e
Author: Elliott Sales de Andrade <esalesde at physics.utoronto.ca>
Date:   Sun Jun 1 21:14:12 2014 -0400

    Replace bubble sort with heap sort.
    
    Probably faster, and it saves a couple temporary arrays, but at least the
    name is no longer false.


>---------------------------------------------------------------

968b09ad64560cfe4362140719ce5aca0036288e
 src/meshfem3D/model_attenuation.f90 | 116 +++++++++++++++++++++++-------------
 1 file changed, 74 insertions(+), 42 deletions(-)

diff --git a/src/meshfem3D/model_attenuation.f90 b/src/meshfem3D/model_attenuation.f90
index a7ac26c..2699ad3 100644
--- a/src/meshfem3D/model_attenuation.f90
+++ b/src/meshfem3D/model_attenuation.f90
@@ -939,10 +939,8 @@ subroutine attenuation_simplex_setup(nf_in,nsls_in,f_in,Q_in,tau_s_in,AS_V)
 
   double precision rho, chi, psi, sigma
   double precision xin(n), y(n), v(n,n+1), fv(n+1)
-  double precision vtmp(n,n+1)
   double precision usual_delta, zero_term_delta
   double precision xbar(n), xr(n), fxr, xe(n), fxe, xc(n), fxc, fxcc, xcc(n)
-  integer place(n+1)
 
   double precision max_size_simplex, max_value
 
@@ -993,12 +991,7 @@ subroutine attenuation_simplex_setup(nf_in,nsls_in,f_in,Q_in,tau_s_in,AS_V)
      fv(j+1) = funk(x,AS_V)
   enddo
 
-  call qsort_local(fv,n+1,place)
-
-  do i = 1,n+1
-     vtmp(:,i) = v(:,place(i))
-  enddo
-  v = vtmp
+  call heap_sort_local(n+1, fv, v)
 
   how = initial
   itercount = 1
@@ -1099,11 +1092,7 @@ subroutine attenuation_simplex_setup(nf_in,nsls_in,f_in,Q_in,tau_s_in,AS_V)
         endif
      endif
 
-     call qsort_local(fv,n+1,place)
-     do i = 1,n+1
-        vtmp(:,i) = v(:,place(i))
-     enddo
-     v = vtmp
+     call heap_sort_local(n+1, fv, v)
 
      itercount = itercount + 1
      if (prnt == 3) then
@@ -1208,52 +1197,95 @@ subroutine attenuation_simplex_setup(nf_in,nsls_in,f_in,Q_in,tau_s_in,AS_V)
 !-------------------------------------------------------------------------------------------------
 !
 
-!    - Implementation of a Bubble Sort Routine
+!    - Implementation of a Heap Sort Routine
 !    Input
+!      n = Input
+!         Length of arrays
 !      X = Input/Output
 !         Vector to be sorted
 !         dimension(n)
-!      n = Input
-!         Length of X
-!      I = Output
-!         Sorted Indices of vector X
+!      Y = Input/Output
+!         Vector to be sorted alongside X
+!         dimension(n)
 !
 !      Example:
 !         X = [ 4 3 1 2 ] on Input
-!         I = [ 1 2 3 4 ] Computed Internally (in order)
+!         Y = [ 1 2 3 4 ] on Input
 !
 !         X = [ 1 2 3 4 ] on Output
-!         I = [ 3 4 2 1 ] on Output
+!         Y = [ 3 4 2 1 ] on Output
 !
-  subroutine qsort_local(X,n,I)
+  subroutine heap_sort_local(N, X, Y)
 
   implicit none
+  integer, intent(in) :: N
+  double precision, dimension(N), intent(inout) :: X
+  double precision, dimension(N), intent(inout) :: Y
 
-  integer n
-  double precision X(n)
-  integer I(n)
+  ! local parameters
+  double precision :: tmp
+  integer :: i
 
-  integer j,k
-  double precision rtmp
-  integer itmp
+  ! checks if anything to do
+  if (N < 2) return
 
-  do j = 1,n
-     I(j) = j
+  ! builds heap
+  do i = N/2, 1, -1
+    call heap_sort_siftdown(i, N)
   enddo
 
-  do j = 1,n
-     do k = 1,n-j
-        if(X(k+1) < X(k)) then
-           rtmp   = X(k)
-           X(k)   = X(k+1)
-           X(k+1) = rtmp
-
-           itmp   = I(k)
-           I(k)   = I(k+1)
-           I(k+1) = itmp
-        endif
-     enddo
+  ! sorts array
+  do i = N, 2, -1
+    ! swaps last and first entry in this section
+    tmp = X(1)
+    X(1) = X(i)
+    X(i) = tmp
+    tmp = Y(1)
+    Y(1) = Y(i)
+    Y(i) = tmp
+
+    call heap_sort_siftdown(1, i - 1)
   enddo
 
-  end subroutine qsort_local
+!
+!----
+!
+
+  contains
+
+    subroutine heap_sort_siftdown(start, bottom)
+
+    implicit none
+
+    integer, intent(in) :: start, bottom
+
+    ! local parameters
+    integer :: i, j
+    double precision :: xtmp, ytmp
+
+    i = start
+    xtmp = X(i)
+    ytmp = Y(i)
+
+    j = 2 * i
+    do while (j <= bottom)
+      ! chooses larger value first in this section
+      if (j < bottom) then
+        if (X(j) <= X(j+1)) j = j + 1
+      endif
+
+      ! checks if section already smaller than initial value
+      if (X(j) < xtmp) exit
+
+      X(i) = X(j)
+      Y(i) = Y(j)
+      i = j
+      j = 2 * i
+    enddo
+
+    X(i) = xtmp
+    Y(i) = ytmp
+
+    end subroutine heap_sort_siftdown
 
+  end subroutine heap_sort_local



More information about the CIG-COMMITS mailing list