module QuickSortM
  !Takes 1, 2, 3, 4.. arrays of same dimension, orders first one and modifies the others acordingly
  use UtilitiesM
  implicit none
  public

  interface swap
     module procedure swapInt
     module procedure swapReal
  end interface swap

  interface quickSort
     module procedure quickSort1vectI
     module procedure quickSort1vectR
     module procedure quickSort2vectII
     module procedure quickSort2vectIR
     module procedure quickSort2vectRR
     module procedure quickSort2vectRI
     module procedure quickSort3vectIII
     module procedure quickSort3vectIIR
     module procedure quickSort3vectIRI
     module procedure quickSort3vectIRR
     module procedure quickSort3vectRRR
     module procedure quickSort3vectRRI
     module procedure quickSort3vectRIR
     module procedure quickSort3vectRII
     module procedure quickSort4vectIIII
     module procedure quickSort4vectIIIR
     module procedure quickSort4vectIIRI
     module procedure quickSort4vectIIRR
     module procedure quickSort4vectIRII
     module procedure quickSort4vectIRIR
     module procedure quickSort4vectIRRI
     module procedure quickSort4vectIRRR
     module procedure quickSort4vectRIII
     module procedure quickSort4vectRIIR
     module procedure quickSort4vectRIRI
     module procedure quickSort4vectRIRR
     module procedure quickSort4vectRRII
     module procedure quickSort4vectRRIR
     module procedure quickSort4vectRRRI
     module procedure quickSort4vectRRRR
  end interface quickSort

contains

  recursive subroutine quickSort1vectR(vect1, low, high)
    implicit none
    real(rkind), dimension(:), intent(InOut) :: vect1
    integer(ikind), intent(In) :: low, high
    integer(ikind) i, iPivot, j
    iPivot = high
    i = low
    do while(iPivot > i)
       if (vect1(i) > vect1(iPivot)) then
          call swap(vect1(i), vect1(iPivot-1))
          call swap(vect1(iPivot-1), vect1(iPivot))
          iPivot = iPivot - 1
       else
          i=i+1
       end if
    end do
    if (low < high) then
       call quickSort(vect1, low, iPivot-1)
       call quickSort(vect1, iPivot+1, high)
    end if
  end subroutine quickSort1vectR

  recursive subroutine quickSort1vectI(vect1, low, high)
    implicit none
    integer(ikind), dimension(:), intent(InOut) :: vect1
    integer(ikind), intent(In) :: low, high
    integer(ikind) i, iPivot, j
    iPivot = high
    i = low
    do while(iPivot > i)
       if (vect1(i) > vect1(iPivot)) then
          call swap(vect1(i), vect1(iPivot-1))
          call swap(vect1(iPivot-1), vect1(iPivot))
          iPivot = iPivot - 1
       else
          i=i+1
       end if
    end do
    if (low < high) then
       call quickSort(vect1, low, iPivot-1)
       call quickSort(vect1, iPivot+1, high)
    end if
  end subroutine quickSort1vectI

  recursive subroutine quickSort2vectIR(vect1, vect2, low, high)
    implicit none
    integer(ikind), dimension(:), intent(InOut) :: vect1
    real(rkind), dimension(:), intent(InOut) :: vect2
    integer(ikind), intent(In) :: low, high
    integer(ikind) i, iPivot, j
    iPivot = high
    i = low
    do while(iPivot > i)
       if (vect1(i) > vect1(iPivot)) then
          call swap(vect1(i), vect1(iPivot-1))
          call swap(vect2(i), vect2(iPivot-1))
          call swap(vect1(iPivot-1), vect1(iPivot))
          call swap(vect2(iPivot-1), vect2(iPivot))
          iPivot = iPivot - 1
       else
          i=i+1
       end if
    end do
    if (low < high) then
       call quickSort(vect1, vect2, low, iPivot-1)
       call quickSort(vect1, vect2, iPivot+1, high)
    end if
  end subroutine quickSort2vectIR

  recursive subroutine quickSort2vectII(vect1, vect2, low, high)
    implicit none
    integer(ikind), dimension(:), intent(InOut) :: vect1
    integer(ikind), dimension(:), intent(InOut) :: vect2
    integer(ikind), intent(In) :: low, high
    integer(ikind) i, iPivot, j
    iPivot = high
    i = low
    do while(iPivot > i)
       if (vect1(i) > vect1(iPivot)) then
          call swap(vect1(i), vect1(iPivot-1))
          call swap(vect2(i), vect2(iPivot-1))
          call swap(vect1(iPivot-1), vect1(iPivot))
          call swap(vect2(iPivot-1), vect2(iPivot))
          iPivot = iPivot - 1
       else
          i=i+1
       end if
    end do
    if (low < high) then
       call quickSort(vect1, vect2, low, iPivot-1)
       call quickSort(vect1, vect2, iPivot+1, high)
    end if
  end subroutine quickSort2vectII

  recursive subroutine quickSort2vectRI(vect1, vect2, low, high)
    implicit none
    real(rkind), dimension(:), intent(InOut) :: vect1
    integer(ikind), dimension(:), intent(InOut) :: vect2
    integer(ikind), intent(In) :: low, high
    integer(ikind) i, iPivot, j
    iPivot = high
    i = low
    do while(iPivot > i)
       if (vect1(i) > vect1(iPivot)) then
          call swap(vect1(i), vect1(iPivot-1))
          call swap(vect2(i), vect2(iPivot-1))
          call swap(vect1(iPivot-1), vect1(iPivot))
          call swap(vect2(iPivot-1), vect2(iPivot))
          iPivot = iPivot - 1
       else
          i=i+1
       end if
    end do
    if (low < high) then
       call quickSort(vect1, vect2, low, iPivot-1)
       call quickSort(vect1, vect2, iPivot+1, high)
    end if
  end subroutine quickSort2vectRI

  recursive subroutine quickSort2vectRR(vect1, vect2, low, high)
    implicit none
    real(rkind), dimension(:), intent(InOut) :: vect1
    real(rkind), dimension(:), intent(InOut) :: vect2
    integer(ikind), intent(In) :: low, high
    integer(ikind) i, iPivot, j
    iPivot = high
    i = low
    do while(iPivot > i)
       if (vect1(i) > vect1(iPivot)) then
          call swap(vect1(i), vect1(iPivot-1))
          call swap(vect2(i), vect2(iPivot-1))
          call swap(vect1(iPivot-1), vect1(iPivot))
          call swap(vect2(iPivot-1), vect2(iPivot))
          iPivot = iPivot - 1
       else
          i=i+1
       end if
    end do
    if (low < high) then
       call quickSort(vect1, vect2, low, iPivot-1)
       call quickSort(vect1, vect2, iPivot+1, high)
    end if
  end subroutine quickSort2vectRR

  recursive subroutine quickSort3vectIII(vect1, vect2, vect3, low, high)
    implicit none
    integer(ikind), dimension(:), intent(InOut) :: vect1, vect2, vect3
    integer(ikind), intent(In) :: low, high
    integer(ikind) i, iPivot, j
    iPivot = high
    i = low
    do while(iPivot > i)
       if (vect1(i) > vect1(iPivot)) then
          call swap(vect1(i), vect1(iPivot-1))
          call swap(vect2(i), vect2(iPivot-1))
          call swap(vect3(i), vect3(iPivot-1))
          call swap(vect1(iPivot-1), vect1(iPivot))
          call swap(vect2(iPivot-1), vect2(iPivot))
          call swap(vect3(iPivot-1), vect3(iPivot))
          iPivot = iPivot - 1
       else
          i=i+1
       end if
    end do
    if (low < high) then
       call quickSort(vect1, vect2, vect3, low, iPivot-1)
       call quickSort(vect1, vect2, vect3, iPivot+1, high)
    end if
  end subroutine quickSort3vectIII

  recursive subroutine quickSort3vectIIR(vect1, vect2, vect3, low, high)
    implicit none
    integer(ikind), dimension(:), intent(InOut) :: vect1, vect2
    real(rkind), dimension(:), intent(InOut) :: vect3
    integer(ikind), intent(In) :: low, high
    integer(ikind) i, iPivot, j
    iPivot = high
    i = low
    do while(iPivot > i)
       if (vect1(i) > vect1(iPivot)) then
          call swap(vect1(i), vect1(iPivot-1))
          call swap(vect2(i), vect2(iPivot-1))
          call swap(vect3(i), vect3(iPivot-1))
          call swap(vect1(iPivot-1), vect1(iPivot))
          call swap(vect2(iPivot-1), vect2(iPivot))
          call swap(vect3(iPivot-1), vect3(iPivot))
          iPivot = iPivot - 1
       else
          i=i+1
       end if
    end do
    if (low < high) then
       call quickSort(vect1, vect2, vect3, low, iPivot-1)
       call quickSort(vect1, vect2, vect3, iPivot+1, high)
    end if
  end subroutine quickSort3vectIIR

  recursive subroutine quickSort3vectIRR(vect1, vect2, vect3, low, high)
    implicit none
    integer(ikind), dimension(:), intent(InOut) :: vect1
    real(rkind), dimension(:), intent(InOut) :: vect2, vect3
    integer(ikind), intent(In) :: low, high
    integer(ikind) i, iPivot, j
    iPivot = high
    i = low
    do while(iPivot > i)
       if (vect1(i) > vect1(iPivot)) then
          call swap(vect1(i), vect1(iPivot-1))
          call swap(vect2(i), vect2(iPivot-1))
          call swap(vect3(i), vect3(iPivot-1))
          call swap(vect1(iPivot-1), vect1(iPivot))
          call swap(vect2(iPivot-1), vect2(iPivot))
          call swap(vect3(iPivot-1), vect3(iPivot))
          iPivot = iPivot - 1
       else
          i=i+1
       end if
    end do
    if (low < high) then
       call quickSort(vect1, vect2, vect3, low, iPivot-1)
       call quickSort(vect1, vect2, vect3, iPivot+1, high)
    end if
  end subroutine quickSort3vectIRR

  recursive subroutine quickSort3vectIRI(vect1, vect2, vect3, low, high)
    implicit none
    integer(ikind), dimension(:), intent(InOut) :: vect1, vect3
    real(rkind), dimension(:), intent(InOut) :: vect2
    integer(ikind), intent(In) :: low, high
    integer(ikind) i, iPivot, j
    iPivot = high
    i = low
    do while(iPivot > i)
       if (vect1(i) > vect1(iPivot)) then
          call swap(vect1(i), vect1(iPivot-1))
          call swap(vect2(i), vect2(iPivot-1))
          call swap(vect3(i), vect3(iPivot-1))
          call swap(vect1(iPivot-1), vect1(iPivot))
          call swap(vect2(iPivot-1), vect2(iPivot))
          call swap(vect3(iPivot-1), vect3(iPivot))
          iPivot = iPivot - 1
       else
          i=i+1
       end if
    end do
    if (low < high) then
       call quickSort(vect1, vect2, vect3, low, iPivot-1)
       call quickSort(vect1, vect2, vect3, iPivot+1, high)
    end if
  end subroutine quickSort3vectIRI

  recursive subroutine quickSort3vectRRR(vect1, vect2, vect3, low, high)
    implicit none
    real(rkind), dimension(:), intent(InOut) :: vect1, vect2, vect3
    integer(ikind), intent(In) :: low, high
    integer(ikind) i, iPivot, j
    iPivot = high
    i = low
    do while(iPivot > i)
       if (vect1(i) > vect1(iPivot)) then
          call swap(vect1(i), vect1(iPivot-1))
          call swap(vect2(i), vect2(iPivot-1))
          call swap(vect3(i), vect3(iPivot-1))
          call swap(vect1(iPivot-1), vect1(iPivot))
          call swap(vect2(iPivot-1), vect2(iPivot))
          call swap(vect3(iPivot-1), vect3(iPivot))
          iPivot = iPivot - 1
       else
          i=i+1
       end if
    end do
    if (low < high) then
       call quickSort(vect1, vect2, vect3, low, iPivot-1)
       call quickSort(vect1, vect2, vect3, iPivot+1, high)
    end if
  end subroutine quickSort3vectRRR

  recursive subroutine quickSort3vectRRI(vect1, vect2, vect3, low, high)
    implicit none
    integer(ikind), dimension(:), intent(InOut) :: vect3
    real(rkind), dimension(:), intent(InOut) :: vect1, vect2
    integer(ikind), intent(In) :: low, high
    integer(ikind) i, iPivot, j
    iPivot = high
    i = low
    do while(iPivot > i)
       if (vect1(i) > vect1(iPivot)) then
          call swap(vect1(i), vect1(iPivot-1))
          call swap(vect2(i), vect2(iPivot-1))
          call swap(vect3(i), vect3(iPivot-1))
          call swap(vect1(iPivot-1), vect1(iPivot))
          call swap(vect2(iPivot-1), vect2(iPivot))
          call swap(vect3(iPivot-1), vect3(iPivot))
          iPivot = iPivot - 1
       else
          i=i+1
       end if
    end do
    if (low < high) then
       call quickSort(vect1, vect2, vect3, low, iPivot-1)
       call quickSort(vect1, vect2, vect3, iPivot+1, high)
    end if
  end subroutine quickSort3vectRRI

  recursive subroutine quickSort3vectRIR(vect1, vect2, vect3, low, high)
    implicit none
    integer(ikind), dimension(:), intent(InOut) :: vect2
    real(rkind), dimension(:), intent(InOut) :: vect1, vect3
    integer(ikind), intent(In) :: low, high
    integer(ikind) i, iPivot, j
    iPivot = high
    i = low
    do while(iPivot > i)
       if (vect1(i) > vect1(iPivot)) then
          call swap(vect1(i), vect1(iPivot-1))
          call swap(vect2(i), vect2(iPivot-1))
          call swap(vect3(i), vect3(iPivot-1))
          call swap(vect1(iPivot-1), vect1(iPivot))
          call swap(vect2(iPivot-1), vect2(iPivot))
          call swap(vect3(iPivot-1), vect3(iPivot))
          iPivot = iPivot - 1
       else
          i=i+1
       end if
    end do
    if (low < high) then
       call quickSort(vect1, vect2, vect3, low, iPivot-1)
       call quickSort(vect1, vect2, vect3, iPivot+1, high)
    end if
  end subroutine quickSort3vectRIR

  recursive subroutine quickSort3vectRII(vect1, vect2, vect3, low, high)
    implicit none
    integer(ikind), dimension(:), intent(InOut) :: vect2, vect3
    real(rkind), dimension(:), intent(InOut) :: vect1
    integer(ikind), intent(In) :: low, high
    integer(ikind) i, iPivot, j
    iPivot = high
    i = low
    do while(iPivot > i)
       if (vect1(i) > vect1(iPivot)) then
          call swap(vect1(i), vect1(iPivot-1))
          call swap(vect2(i), vect2(iPivot-1))
          call swap(vect3(i), vect3(iPivot-1))
          call swap(vect1(iPivot-1), vect1(iPivot))
          call swap(vect2(iPivot-1), vect2(iPivot))
          call swap(vect3(iPivot-1), vect3(iPivot))
          iPivot = iPivot - 1
       else
          i=i+1
       end if
    end do
    if (low < high) then
       call quickSort(vect1, vect2, vect3, low, iPivot-1)
       call quickSort(vect1, vect2, vect3, iPivot+1, high)
    end if
  end subroutine quickSort3vectRII

  recursive subroutine quickSort4vectIIII(vect1, vect2, vect3, vect4, low, high)
    implicit none
    integer(ikind), dimension(:), intent(InOut) :: vect1, vect2, vect3, vect4
    integer(ikind), intent(In) :: low, high
    integer(ikind) i, iPivot, j
    iPivot = high
    i = low
    do while(iPivot > i)
       if (vect1(i) > vect1(iPivot)) then
          call swap(vect1(i), vect1(iPivot-1))
          call swap(vect2(i), vect2(iPivot-1))
          call swap(vect3(i), vect3(iPivot-1))
          call swap(vect4(i), vect4(iPivot-1))
          call swap(vect1(iPivot-1), vect1(iPivot))
          call swap(vect2(iPivot-1), vect2(iPivot))
          call swap(vect3(iPivot-1), vect3(iPivot))
          call swap(vect4(iPivot-1), vect4(iPivot))
          iPivot = iPivot - 1
       else
          i=i+1
       end if
    end do
    if (low < high) then
       call quickSort(vect1, vect2, vect3, vect4, low, iPivot-1)
       call quickSort(vect1, vect2, vect3, vect4, iPivot+1, high)
    end if
  end subroutine quickSort4vectIIII

  recursive subroutine quickSort4vectIIIR(vect1, vect2, vect3, vect4, low, high)
    implicit none
    integer(ikind), dimension(:), intent(InOut) :: vect1, vect2, vect3
    real(rkind), dimension(:), intent(inout) :: vect4
    integer(ikind), intent(In) :: low, high
    integer(ikind) i, iPivot, j
    iPivot = high
    i = low
    do while(iPivot > i)
       if (vect1(i) > vect1(iPivot)) then
          call swap(vect1(i), vect1(iPivot-1))
          call swap(vect2(i), vect2(iPivot-1))
          call swap(vect3(i), vect3(iPivot-1))
          call swap(vect4(i), vect4(iPivot-1))
          call swap(vect1(iPivot-1), vect1(iPivot))
          call swap(vect2(iPivot-1), vect2(iPivot))
          call swap(vect3(iPivot-1), vect3(iPivot))
          call swap(vect4(iPivot-1), vect4(iPivot))
          iPivot = iPivot - 1
       else
          i=i+1
       end if
    end do
    if (low < high) then
       call quickSort(vect1, vect2, vect3, vect4, low, iPivot-1)
       call quickSort(vect1, vect2, vect3, vect4, iPivot+1, high)
    end if
  end subroutine quickSort4vectIIIR

  recursive subroutine quickSort4vectIIRI(vect1, vect2, vect3, vect4, low, high)
    implicit none
    integer(ikind), dimension(:), intent(InOut) :: vect1, vect2, vect4
    real(rkind), dimension(:), intent(inout) :: vect3
    integer(ikind), intent(In) :: low, high
    integer(ikind) i, iPivot, j
    iPivot = high
    i = low
    do while(iPivot > i)
       if (vect1(i) > vect1(iPivot)) then
          call swap(vect1(i), vect1(iPivot-1))
          call swap(vect2(i), vect2(iPivot-1))
          call swap(vect3(i), vect3(iPivot-1))
          call swap(vect4(i), vect4(iPivot-1))
          call swap(vect1(iPivot-1), vect1(iPivot))
          call swap(vect2(iPivot-1), vect2(iPivot))
          call swap(vect3(iPivot-1), vect3(iPivot))
          call swap(vect4(iPivot-1), vect4(iPivot))
          iPivot = iPivot - 1
       else
          i=i+1
       end if
    end do
    if (low < high) then
       call quickSort(vect1, vect2, vect3, vect4, low, iPivot-1)
       call quickSort(vect1, vect2, vect3, vect4, iPivot+1, high)
    end if
  end subroutine quickSort4vectIIRI

  recursive subroutine quickSort4vectIIRR(vect1, vect2, vect3, vect4, low, high)
    implicit none
    integer(ikind), dimension(:), intent(InOut) :: vect1, vect2
    real(rkind), dimension(:), intent(inout) :: vect3, vect4
    integer(ikind), intent(In) :: low, high
    integer(ikind) i, iPivot, j
    iPivot = high
    i = low
    do while(iPivot > i)
       if (vect1(i) > vect1(iPivot)) then
          call swap(vect1(i), vect1(iPivot-1))
          call swap(vect2(i), vect2(iPivot-1))
          call swap(vect3(i), vect3(iPivot-1))
          call swap(vect4(i), vect4(iPivot-1))
          call swap(vect1(iPivot-1), vect1(iPivot))
          call swap(vect2(iPivot-1), vect2(iPivot))
          call swap(vect3(iPivot-1), vect3(iPivot))
          call swap(vect4(iPivot-1), vect4(iPivot))
          iPivot = iPivot - 1
       else
          i=i+1
       end if
    end do
    if (low < high) then
       call quickSort(vect1, vect2, vect3, vect4, low, iPivot-1)
       call quickSort(vect1, vect2, vect3, vect4, iPivot+1, high)
    end if
  end subroutine quickSort4vectIIRR

  recursive subroutine quickSort4vectIRRR(vect1, vect2, vect3, vect4, low, high)
    implicit none
    integer(ikind), dimension(:), intent(InOut) :: vect1
    real(rkind), dimension(:), intent(inout) :: vect2, vect3, vect4
    integer(ikind), intent(In) :: low, high
    integer(ikind) i, iPivot, j
    iPivot = high
    i = low
    do while(iPivot > i)
       if (vect1(i) > vect1(iPivot)) then
          call swap(vect1(i), vect1(iPivot-1))
          call swap(vect2(i), vect2(iPivot-1))
          call swap(vect3(i), vect3(iPivot-1))
          call swap(vect4(i), vect4(iPivot-1))
          call swap(vect1(iPivot-1), vect1(iPivot))
          call swap(vect2(iPivot-1), vect2(iPivot))
          call swap(vect3(iPivot-1), vect3(iPivot))
          call swap(vect4(iPivot-1), vect4(iPivot))
          iPivot = iPivot - 1
       else
          i=i+1
       end if
    end do
    if (low < high) then
       call quickSort(vect1, vect2, vect3, vect4, low, iPivot-1)
       call quickSort(vect1, vect2, vect3, vect4, iPivot+1, high)
    end if
  end subroutine quickSort4vectIRRR

  recursive subroutine quickSort4vectIRRI(vect1, vect2, vect3, vect4, low, high)
    implicit none
    integer(ikind), dimension(:), intent(InOut) :: vect1, vect4
    real(rkind), dimension(:), intent(inout) :: vect2, vect3
    integer(ikind), intent(In) :: low, high
    integer(ikind) i, iPivot, j
    iPivot = high
    i = low
    do while(iPivot > i)
       if (vect1(i) > vect1(iPivot)) then
          call swap(vect1(i), vect1(iPivot-1))
          call swap(vect2(i), vect2(iPivot-1))
          call swap(vect3(i), vect3(iPivot-1))
          call swap(vect4(i), vect4(iPivot-1))
          call swap(vect1(iPivot-1), vect1(iPivot))
          call swap(vect2(iPivot-1), vect2(iPivot))
          call swap(vect3(iPivot-1), vect3(iPivot))
          call swap(vect4(iPivot-1), vect4(iPivot))
          iPivot = iPivot - 1
       else
          i=i+1
       end if
    end do
    if (low < high) then
       call quickSort(vect1, vect2, vect3, vect4, low, iPivot-1)
       call quickSort(vect1, vect2, vect3, vect4, iPivot+1, high)
    end if
  end subroutine quickSort4vectIRRI

  recursive subroutine quickSort4vectIRIR(vect1, vect2, vect3, vect4, low, high)
    implicit none
    integer(ikind), dimension(:), intent(InOut) :: vect1, vect3
    real(rkind), dimension(:), intent(inout) :: vect2, vect4
    integer(ikind), intent(In) :: low, high
    integer(ikind) i, iPivot, j
    iPivot = high
    i = low
    do while(iPivot > i)
       if (vect1(i) > vect1(iPivot)) then
          call swap(vect1(i), vect1(iPivot-1))
          call swap(vect2(i), vect2(iPivot-1))
          call swap(vect3(i), vect3(iPivot-1))
          call swap(vect4(i), vect4(iPivot-1))
          call swap(vect1(iPivot-1), vect1(iPivot))
          call swap(vect2(iPivot-1), vect2(iPivot))
          call swap(vect3(iPivot-1), vect3(iPivot))
          call swap(vect4(iPivot-1), vect4(iPivot))
          iPivot = iPivot - 1
       else
          i=i+1
       end if
    end do
    if (low < high) then
       call quickSort(vect1, vect2, vect3, vect4, low, iPivot-1)
       call quickSort(vect1, vect2, vect3, vect4, iPivot+1, high)
    end if
  end subroutine quickSort4vectIRIR

  recursive subroutine quickSort4vectIRII(vect1, vect2, vect3, vect4, low, high)
    implicit none
    integer(ikind), dimension(:), intent(InOut) :: vect1, vect3, vect4
    real(rkind), dimension(:), intent(inout) :: vect2
    integer(ikind), intent(In) :: low, high
    integer(ikind) i, iPivot, j
    iPivot = high
    i = low
    do while(iPivot > i)
       if (vect1(i) > vect1(iPivot)) then
          call swap(vect1(i), vect1(iPivot-1))
          call swap(vect2(i), vect2(iPivot-1))
          call swap(vect3(i), vect3(iPivot-1))
          call swap(vect4(i), vect4(iPivot-1))
          call swap(vect1(iPivot-1), vect1(iPivot))
          call swap(vect2(iPivot-1), vect2(iPivot))
          call swap(vect3(iPivot-1), vect3(iPivot))
          call swap(vect4(iPivot-1), vect4(iPivot))
          iPivot = iPivot - 1
       else
          i=i+1
       end if
    end do
    if (low < high) then
       call quickSort(vect1, vect2, vect3, vect4, low, iPivot-1)
       call quickSort(vect1, vect2, vect3, vect4, iPivot+1, high)
    end if
  end subroutine quickSort4vectIRII

  recursive subroutine quickSort4vectRRRR(vect1, vect2, vect3, vect4, low, high)
    implicit none
    real(rkind), dimension(:), intent(InOut) :: vect1, vect2, vect3, vect4
    integer(ikind), intent(In) :: low, high
    integer(ikind) i, iPivot, j
    iPivot = high
    i = low
    do while(iPivot > i)
       if (vect1(i) > vect1(iPivot)) then
          call swap(vect1(i), vect1(iPivot-1))
          call swap(vect2(i), vect2(iPivot-1))
          call swap(vect3(i), vect3(iPivot-1))
          call swap(vect4(i), vect4(iPivot-1))
          call swap(vect1(iPivot-1), vect1(iPivot))
          call swap(vect2(iPivot-1), vect2(iPivot))
          call swap(vect3(iPivot-1), vect3(iPivot))
          call swap(vect4(iPivot-1), vect4(iPivot))
          iPivot = iPivot - 1
       else
          i=i+1
       end if
    end do
    if (low < high) then
       call quickSort(vect1, vect2, vect3, vect4, low, iPivot-1)
       call quickSort(vect1, vect2, vect3, vect4, iPivot+1, high)
    end if
  end subroutine quickSort4vectRRRR

  recursive subroutine quickSort4vectRRRI(vect1, vect2, vect3, vect4, low, high)
    implicit none
    integer(ikind), dimension(:), intent(InOut) :: vect4
    real(rkind), dimension(:), intent(inout) :: vect1, vect2, vect3
    integer(ikind), intent(In) :: low, high
    integer(ikind) i, iPivot, j
    iPivot = high
    i = low
    do while(iPivot > i)
       if (vect1(i) > vect1(iPivot)) then
          call swap(vect1(i), vect1(iPivot-1))
          call swap(vect2(i), vect2(iPivot-1))
          call swap(vect3(i), vect3(iPivot-1))
          call swap(vect4(i), vect4(iPivot-1))
          call swap(vect1(iPivot-1), vect1(iPivot))
          call swap(vect2(iPivot-1), vect2(iPivot))
          call swap(vect3(iPivot-1), vect3(iPivot))
          call swap(vect4(iPivot-1), vect4(iPivot))
          iPivot = iPivot - 1
       else
          i=i+1
       end if
    end do
    if (low < high) then
       call quickSort(vect1, vect2, vect3, vect4, low, iPivot-1)
       call quickSort(vect1, vect2, vect3, vect4, iPivot+1, high)
    end if
  end subroutine quickSort4vectRRRI

  recursive subroutine quickSort4vectRRIR(vect1, vect2, vect3, vect4, low, high)
    implicit none
    integer(ikind), dimension(:), intent(InOut) :: vect3
    real(rkind), dimension(:), intent(inout) :: vect1, vect2, vect4
    integer(ikind), intent(In) :: low, high
    integer(ikind) i, iPivot, j
    iPivot = high
    i = low
    do while(iPivot > i)
       if (vect1(i) > vect1(iPivot)) then
          call swap(vect1(i), vect1(iPivot-1))
          call swap(vect2(i), vect2(iPivot-1))
          call swap(vect3(i), vect3(iPivot-1))
          call swap(vect4(i), vect4(iPivot-1))
          call swap(vect1(iPivot-1), vect1(iPivot))
          call swap(vect2(iPivot-1), vect2(iPivot))
          call swap(vect3(iPivot-1), vect3(iPivot))
          call swap(vect4(iPivot-1), vect4(iPivot))
          iPivot = iPivot - 1
       else
          i=i+1
       end if
    end do
    if (low < high) then
       call quickSort(vect1, vect2, vect3, vect4, low, iPivot-1)
       call quickSort(vect1, vect2, vect3, vect4, iPivot+1, high)
    end if
  end subroutine quickSort4vectRRIR

  recursive subroutine quickSort4vectRRII(vect1, vect2, vect3, vect4, low, high)
    implicit none
    integer(ikind), dimension(:), intent(InOut) :: vect3, vect4
    real(rkind), dimension(:), intent(inout) :: vect1, vect2
    integer(ikind), intent(In) :: low, high
    integer(ikind) i, iPivot, j
    iPivot = high
    i = low
    do while(iPivot > i)
       if (vect1(i) > vect1(iPivot)) then
          call swap(vect1(i), vect1(iPivot-1))
          call swap(vect2(i), vect2(iPivot-1))
          call swap(vect3(i), vect3(iPivot-1))
          call swap(vect4(i), vect4(iPivot-1))
          call swap(vect1(iPivot-1), vect1(iPivot))
          call swap(vect2(iPivot-1), vect2(iPivot))
          call swap(vect3(iPivot-1), vect3(iPivot))
          call swap(vect4(iPivot-1), vect4(iPivot))
          iPivot = iPivot - 1
       else
          i=i+1
       end if
    end do
    if (low < high) then
       call quickSort(vect1, vect2, vect3, vect4, low, iPivot-1)
       call quickSort(vect1, vect2, vect3, vect4, iPivot+1, high)
    end if
  end subroutine quickSort4vectRRII

  recursive subroutine quickSort4vectRIRR(vect1, vect2, vect3, vect4, low, high)
    implicit none
    integer(ikind), dimension(:), intent(InOut) :: vect2
    real(rkind), dimension(:), intent(inout) :: vect1, vect3, vect4
    integer(ikind), intent(In) :: low, high
    integer(ikind) i, iPivot, j
    iPivot = high
    i = low
    do while(iPivot > i)
       if (vect1(i) > vect1(iPivot)) then
          call swap(vect1(i), vect1(iPivot-1))
          call swap(vect2(i), vect2(iPivot-1))
          call swap(vect3(i), vect3(iPivot-1))
          call swap(vect4(i), vect4(iPivot-1))
          call swap(vect1(iPivot-1), vect1(iPivot))
          call swap(vect2(iPivot-1), vect2(iPivot))
          call swap(vect3(iPivot-1), vect3(iPivot))
          call swap(vect4(iPivot-1), vect4(iPivot))
          iPivot = iPivot - 1
       else
          i=i+1
       end if
    end do
    if (low < high) then
       call quickSort(vect1, vect2, vect3, vect4, low, iPivot-1)
       call quickSort(vect1, vect2, vect3, vect4, iPivot+1, high)
    end if
  end subroutine quickSort4vectRIRR

  recursive subroutine quickSort4vectRIRI(vect1, vect2, vect3, vect4, low, high)
    implicit none
    integer(ikind), dimension(:), intent(InOut) :: vect2, vect4
    real(rkind), dimension(:), intent(inout) :: vect1, vect3
    integer(ikind), intent(In) :: low, high
    integer(ikind) i, iPivot, j
    iPivot = high
    i = low
    do while(iPivot > i)
       if (vect1(i) > vect1(iPivot)) then
          call swap(vect1(i), vect1(iPivot-1))
          call swap(vect2(i), vect2(iPivot-1))
          call swap(vect3(i), vect3(iPivot-1))
          call swap(vect4(i), vect4(iPivot-1))
          call swap(vect1(iPivot-1), vect1(iPivot))
          call swap(vect2(iPivot-1), vect2(iPivot))
          call swap(vect3(iPivot-1), vect3(iPivot))
          call swap(vect4(iPivot-1), vect4(iPivot))
          iPivot = iPivot - 1
       else
          i=i+1
       end if
    end do
    if (low < high) then
       call quickSort(vect1, vect2, vect3, vect4, low, iPivot-1)
       call quickSort(vect1, vect2, vect3, vect4, iPivot+1, high)
    end if
  end subroutine quickSort4vectRIRI

  recursive subroutine quickSort4vectRIIR(vect1, vect2, vect3, vect4, low, high)
    implicit none
    integer(ikind), dimension(:), intent(InOut) :: vect2, vect3
    real(rkind), dimension(:), intent(inout) :: vect1, vect4
    integer(ikind), intent(In) :: low, high
    integer(ikind) i, iPivot, j
    iPivot = high
    i = low
    do while(iPivot > i)
       if (vect1(i) > vect1(iPivot)) then
          call swap(vect1(i), vect1(iPivot-1))
          call swap(vect2(i), vect2(iPivot-1))
          call swap(vect3(i), vect3(iPivot-1))
          call swap(vect4(i), vect4(iPivot-1))
          call swap(vect1(iPivot-1), vect1(iPivot))
          call swap(vect2(iPivot-1), vect2(iPivot))
          call swap(vect3(iPivot-1), vect3(iPivot))
          call swap(vect4(iPivot-1), vect4(iPivot))
          iPivot = iPivot - 1
       else
          i=i+1
       end if
    end do
    if (low < high) then
       call quickSort(vect1, vect2, vect3, vect4, low, iPivot-1)
       call quickSort(vect1, vect2, vect3, vect4, iPivot+1, high)
    end if
  end subroutine quickSort4vectRIIR

  recursive subroutine quickSort4vectRIII(vect1, vect2, vect3, vect4, low, high)
    implicit none
    integer(ikind), dimension(:), intent(InOut) :: vect2, vect3, vect4
    real(rkind), dimension(:), intent(inout) :: vect1
    integer(ikind), intent(In) :: low, high
    integer(ikind) i, iPivot, j
    iPivot = high
    i = low
    do while(iPivot > i)
       if (vect1(i) > vect1(iPivot)) then
          call swap(vect1(i), vect1(iPivot-1))
          call swap(vect2(i), vect2(iPivot-1))
          call swap(vect3(i), vect3(iPivot-1))
          call swap(vect4(i), vect4(iPivot-1))
          call swap(vect1(iPivot-1), vect1(iPivot))
          call swap(vect2(iPivot-1), vect2(iPivot))
          call swap(vect3(iPivot-1), vect3(iPivot))
          call swap(vect4(iPivot-1), vect4(iPivot))
          iPivot = iPivot - 1
       else
          i=i+1
       end if
    end do
    if (low < high) then
       call quickSort(vect1, vect2, vect3, vect4, low, iPivot-1)
       call quickSort(vect1, vect2, vect3, vect4, iPivot+1, high)
    end if
  end subroutine quickSort4vectRIII

  subroutine swapInt(a,b)
    implicit none
    integer(ikind), intent(InOut) :: a, b
    integer(ikind) ::  aux
    aux = b
    b = a
    a = aux
  end subroutine swapInt

  subroutine swapReal(a,b)
    implicit none
    real(rkind), intent(InOut) :: a, b
    real(rkind) ::  aux
    aux = b
    b = a
    a = aux
  end subroutine swapReal

end module QuickSortM


! { dg-do run }
! Test that the mask is properly converted to the kind type of j in ibits.
program ibits_test
  implicit none
  integer(8), parameter :: n = z'00000000FFFFFFFF' ! { dg-warning "BOZ literal at .1. outside a DATA statement" }
  integer(8) i,j,k,m
  j = 1
  do i=1,70
     j = ishft(j,1) + 1
     k = ibits(j, 0, 32)
     m = iand(j,n)
     if (k /= m) call abort
  end do
end program ibits_test


      subroutine s231 (ntimes,ld,n,ctime,dtime,a,b,c,d,e,aa,bb,cc)
c
c     loop interchange
c     loop with multiple dimension recursion
c
      integer ntimes, ld, n, i, nl, j
      double precision a(n), b(n), c(n), d(n), e(n), aa(ld,n),
     +                 bb(ld,n), cc(ld,n)
      double precision chksum, cs2d
      real t1, t2, second, ctime, dtime

      call init(ld,n,a,b,c,d,e,aa,bb,cc,'s231 ')
      t1 = second()
      do 1 nl = 1,ntimes/n
      do 10 i=1,n
         do 20 j=2,n
            aa(i,j) = aa(i,j-1) + bb(i,j)
   20    continue
   10 continue
      call dummy(ld,n,a,b,c,d,e,aa,bb,cc,1.d0)
   1  continue
      t2 = second() - t1 - ctime - ( dtime * float(ntimes/n) )
      chksum = cs2d(n,aa)
      call check (chksum,(ntimes/n)*n*(n-1),n,t2,'s231 ')
      return
      end

! { dg-final { scan-tree-dump-times "will be interchanged" 1 "graphite" { xfail *-*-* } } }


Function g(y1, y2, pt2)
  Implicit Double Precision (A-H, O-Z)
  Real hipr1(100), hint1(100)
  Common /hparnt/hipr1, ihpr2(50), hint1, ihnt2(50)
  Dimension f(2, 7)
  Save
  xt = 2.D0*dsqrt(pt2)/dble(hint1(1))
  x1 = 0.5D0*xt*(dexp(y1)+dexp(y2))
  x2 = 0.5D0*xt*(dexp(-y1)+dexp(-y2))
  z = dsqrt(1.D0-xt**2/x1/x2)
  ss = x1*x2*dble(hint1(1))**2
  t = -(1.D0-z)/2.D0
  u = -(1.D0+z)/2.D0
  af = 3.D0
  dlam = dble(hipr1(15))
  aph = 12.D0*3.1415926D0/(33.D0-2.D0*af)/dlog(pt2/dlam**2)
  Call parton(f, x1, x2, pt2)
  g11 = ((f(1,1)+f(1,2))*(f(2,3)+f(2,4)+f(2,5)+f(2,6))+(f(1,3)+f(1,4))*(f(2,5)+f(2,6)))*subcr1(t, u)
  g12 = ((f(2,1)+f(2,2))*(f(1,3)+f(1,4)+f(1,5)+f(1,6))+(f(2,3)+f(2,4))*(f(1,5)+f(1,6)))*subcr1(u, t)
  g13 = (f(1,1)*f(2,1)+f(1,2)*f(2,2)+f(1,3)*f(2,3)+f(1,4)*f(2,4)+f(1,5)*f(2,5)+f(1,6)*f(2,6))*(subcr1(u,t)+subcr1(t,u)-8.D0/t/u/27.D0)
  g2 = (af-1)*(f(1,1)*f(2,2)+f(2,1)*f(1,2)+f(1,3)*f(2,4)+f(2,3)*f(1,4)+f(1,5)*f(2,6)+f(2,5)*f(1,6))*subcr2(t, u)
  g31 = (f(1,1)*f(2,2)+f(1,3)*f(2,4)+f(1,5)*f(2,6))*subcr3(t, u)
  g32 = (f(2,1)*f(1,2)+f(2,3)*f(1,4)+f(2,5)*f(1,6))*subcr3(u, t)
  g4 = (f(1,1)*f(2,2)+f(2,1)*f(1,2)+f(1,3)*f(2,4)+f(2,3)*f(1,4)+f(1,5)*f(2,6)+f(2,5)*f(1,6))*subcr4(t, u)
  g5 = af*f(1, 7)*f(2, 7)*subcr5(t, u)
  g61 = f(1, 7)*(f(2,1)+f(2,2)+f(2,3)+f(2,4)+f(2,5)+f(2,6))*subcr6(t, u)
  g62 = f(2, 7)*(f(1,1)+f(1,2)+f(1,3)+f(1,4)+f(1,5)+f(1,6))*subcr6(u, t)
  g7 = f(1, 7)*f(2, 7)*subcr7(t, u)
  g = (g11+g12+g13+g2+g31+g32+g4+g5+g61+g62+g7)*dble(hipr1(17))*3.14159D0*aph**2/ss**2
  Return
End Function g