#if defined HAVE_CONFIG_H
#include "config.h"
#endif
!{\src2tex{textfont=tt}}
!!****m* ABINIT/m_MapHyb
!! NAME
!!  m_MapHyb
!! 
!! FUNCTION 
!!  map template integer/double
!!
!! COPYRIGHT
!!  Copyright (C) 2013-2014 ABINIT group (J. Bieder)
!!  This file is distributed under the terms of the
!!  GNU General Public License, see ~abinit/COPYING
!!  or http://www.gnu.org/copyleft/gpl.txt .
!!
!! NOTES
!!
!! PARENTS
!!  Will be filled automatically by the parent script
!!
!! CHILDREN
!!  Will be filled automatically by the parent script
!!
!! SOURCE

#include "defs.h"
MODULE m_MapHyb
USE m_Global
IMPLICIT NONE

!!***

PRIVATE

!!****t* m_MapHyb/MapHyb
!! NAME
!!  MapHyb
!!
!! FUNCTION
!!  This structured datatype contains the necessary data
!!
!! COPYRIGHT
!!  Copyright (C) 2013-2014 ABINIT group (J. Bieder)
!!  This file is distributed under the terms of the
!!  GNU General Public License, see ~abinit/COPYING
!!  or http://www.gnu.org/copyleft/gpl.txt .
!!
!! SOURCE

TYPE, PUBLIC :: MapHyb
  INTEGER _PRIVATE :: size
  INTEGER         :: tail
  INTEGER         , ALLOCATABLE, DIMENSION(:)         :: listINT
  DOUBLE PRECISION, ALLOCATABLE, DIMENSION(:)         :: listDBLE
END TYPE MapHyb
!!***

INTERFACE MapHyb_sort
  MODULE PROCEDURE MapHyb_quickSort, MapHyb_sort
END INTERFACE

!PUBLIC INTERFACE ASSIGNMENT(=)
!  MODULE PROCEDURE MapHyb_assign
!END INTERFACE

PUBLIC  :: MapHyb_init
PUBLIC  :: MapHyb_setSize
PRIVATE :: MapHyb_enlarge
PUBLIC  :: MapHyb_assign
PUBLIC  :: MapHyb_sort
PUBLIC  :: MapHyb_quickSort
PUBLIC  :: MapHyb_print
PUBLIC  :: MapHyb_clear
PUBLIC  :: MapHyb_destroy

CONTAINS
!!***

!!****f* ABINIT/m_MapHyb/MapHyb_init
!! NAME
!!  MapHyb_init
!!
!! FUNCTION
!!  initialize
!!
!! COPYRIGHT
!!  Copyright (C) 2013-2014 ABINIT group (J. Bieder)
!!  This file is distributed under the terms of the
!!  GNU General Public License, see ~abinit/COPYING
!!  or http://www.gnu.org/copyleft/gpl.txt .
!!
!! INPUTS
!!  map=map
!!  size=memory size for initialization
!!
!! OUTPUT
!!
!! SIDE EFFECTS
!!
!! NOTES
!!
!! PARENTS
!!  Will be filled automatically by the parent script
!!
!! CHILDREN
!!  Will be filled automatically by the parent script
!!
!! SOURCE

SUBROUTINE MapHyb_init(map, size)

!Arguments ------------------------------------

!This section has been created automatically by the script Abilint (TD).
!Do not modify the following lines by hand.
#undef ABI_FUNC
#define ABI_FUNC 'MapHyb_init'
!End of the abilint section

  TYPE(MapHyb)     , INTENT(INOUT) :: map
  INTEGER, OPTIONAL, INTENT(IN   ) :: size
!Local variables ------------------------------
  INTEGER                          :: size_val

  size_val = Global_SIZE
  IF ( PRESENT(size) ) size_val = size
  map%size = size_val
  FREEIF(map%listINT)
  MALLOC(map%listINT,(1:size_val))
  FREEIF(map%listDBLE)
  MALLOC(map%listDBLE,(1:size_val))
  map%tail     = 0
END SUBROUTINE MapHyb_init
!!***

!!****f* ABINIT/m_MapHyb/MapHyb_setSize
!! NAME
!!  MapHyb_setSize
!!
!! FUNCTION
!!  impose size of the map
!!
!! COPYRIGHT
!!  Copyright (C) 2013-2014 ABINIT group (J. Bieder)
!!  This file is distributed under the terms of the
!!  GNU General Public License, see ~abinit/COPYING
!!  or http://www.gnu.org/copyleft/gpl.txt .
!!
!! INPUTS
!!  map=Map
!!  new_tail=new size
!!
!! OUTPUT
!!
!! SIDE EFFECTS
!!
!! NOTES
!!
!! PARENTS
!!  Will be filled automatically by the parent script
!!
!! CHILDREN
!!  Will be filled automatically by the parent script
!!
!! SOURCE

SUBROUTINE MapHyb_setSize(map,new_tail)

!Arguments ------------------------------------

!This section has been created automatically by the script Abilint (TD).
!Do not modify the following lines by hand.
#undef ABI_FUNC
#define ABI_FUNC 'MapHyb_setSize'
!End of the abilint section

  TYPE(MapHyb), INTENT(INOUT) :: map
  INTEGER     , INTENT(IN   ) :: new_tail
!Local variables ------------------------------
  INTEGER                     :: size

  IF ( .NOT. ALLOCATED(map%listINT) ) THEN
    CALL MapHyb_init(map)
  END IF
  size = map%size
  IF( new_tail .GT. size ) THEN
    CALL MapHyb_enlarge(map, MAX(new_tail-size,Global_SIZE))
  END IF
  map%tail = new_tail
END SUBROUTINE MapHyb_setSize  
!!***

!!****f* ABINIT/m_MapHyb/MapHyb_enlarge
!! NAME
!!  MapHyb_enlarge
!!
!! FUNCTION
!!  enlarge memory space
!!
!! COPYRIGHT
!!  Copyright (C) 2013-2014 ABINIT group (J. Bieder)
!!  This file is distributed under the terms of the
!!  GNU General Public License, see ~abinit/COPYING
!!  or http://www.gnu.org/copyleft/gpl.txt .
!!
!! INPUTS
!!  map=Map
!!  size=new memory size
!!
!! OUTPUT
!!
!! SIDE EFFECTS
!!
!! NOTES
!!
!! PARENTS
!!  Will be filled automatically by the parent script
!!
!! CHILDREN
!!  Will be filled automatically by the parent script
!!
!! SOURCE

SUBROUTINE MapHyb_enlarge(map, size)

!Arguments ------------------------------------

!This section has been created automatically by the script Abilint (TD).
!Do not modify the following lines by hand.
#undef ABI_FUNC
#define ABI_FUNC 'MapHyb_enlarge'
!End of the abilint section

  TYPE(MapHyb)     , INTENT(INOUT)       :: map
  INTEGER, OPTIONAL, INTENT(IN   )       :: size
!Local variables ------------------------------
  INTEGER                                :: width
  INTEGER                                :: tail
  INTEGER                                :: size_val
  INTEGER         , ALLOCATABLE, DIMENSION(:) :: listINT_temp 
  DOUBLE PRECISION, ALLOCATABLE, DIMENSION(:) :: listDBLE_temp 

  IF ( ALLOCATED(map%listINT) ) THEN
    FREEIF(listINT_temp)
    width = map%size
    tail  = map%tail
    size_val = width
    IF ( PRESENT(size) ) size_val = size 
    ! listINT enlarge
    MALLOC(listINT_temp,(1:tail))
    listINT_temp(1:tail) = map%listINT(1:tail)
    FREE(map%listINT)
    map%size = width + size_val
    MALLOC(map%listINT,(1:map%size))
    map%listINT(1:tail) = listINT_temp(1:tail)
    FREE(listINT_temp)
    ! listDBLE enlarge
    MALLOC(listDBLE_temp,(1:tail))
    listDBLE_temp(1:tail) = map%listDBLE(1:tail)
    FREE(map%listDBLE)
    MALLOC(map%listDBLE,(1:map%size))
    map%listDBLE(1:tail) = listDBLE_temp(1:tail)
    FREE(listDBLE_temp)
  ELSE
    CALL MapHyb_init(map, Global_SIZE)
  END IF
END SUBROUTINE MapHyb_enlarge
!!***

!!****f* ABINIT/m_MapHyb/MapHyb_assign
!! NAME
!!  MapHyb_assign
!!
!! FUNCTION
!!  assign
!!
!! COPYRIGHT
!!  Copyright (C) 2013-2014 ABINIT group (J. Bieder)
!!  This file is distributed under the terms of the
!!  GNU General Public License, see ~abinit/COPYING
!!  or http://www.gnu.org/copyleft/gpl.txt .
!!
!! INPUTS
!!  map_1=map
!!  map_2=map
!!
!! OUTPUT
!!
!! SIDE EFFECTS
!!
!! NOTES
!!
!! PARENTS
!!  Will be filled automatically by the parent script
!!
!! CHILDREN
!!  Will be filled automatically by the parent script
!!
!! SOURCE

SUBROUTINE MapHyb_assign(map_1, map_2)

!Arguments ------------------------------------

!This section has been created automatically by the script Abilint (TD).
!Do not modify the following lines by hand.
#undef ABI_FUNC
#define ABI_FUNC 'MapHyb_assign'
!End of the abilint section

  TYPE(MapHyb), INTENT(INOUT) :: map_1
  TYPE(MapHyb), INTENT(IN   ) :: map_2
!Local variables ------------------------------
  INTEGER                     :: tail

  tail = map_2%tail
  CALL MapHyb_setSize(map_1, tail)
  map_1%listINT(1:tail) = map_2%listINT(1:tail)
  map_1%listDBLE(1:tail) = map_2%listDBLE(1:tail)

END SUBROUTINE MapHyb_assign
!!***

!!****f* ABINIT/m_MapHyb/MapHyb_sort
!! NAME
!!  MapHyb_sort
!!
!! FUNCTION
!!  sort the map with respect to the integer array
!!
!! COPYRIGHT
!!  Copyright (C) 2013-2014 ABINIT group (J. Bieder)
!!  This file is distributed under the terms of the
!!  GNU General Public License, see ~abinit/COPYING
!!  or http://www.gnu.org/copyleft/gpl.txt .
!!
!! INPUTS
!!  map=Map
!!
!! OUTPUT
!!
!! SIDE EFFECTS
!!
!! NOTES
!!
!! PARENTS
!!  Will be filled automatically by the parent script
!!
!! CHILDREN
!!  Will be filled automatically by the parent script
!!
!! SOURCE

SUBROUTINE MapHyb_sort(map)

!Arguments ------------------------------------

!This section has been created automatically by the script Abilint (TD).
!Do not modify the following lines by hand.
#undef ABI_FUNC
#define ABI_FUNC 'MapHyb_sort'
!End of the abilint section

  TYPE(MapHyb), INTENT(INOUT) :: map
 
  IF ( map%tail .EQ. 1 ) RETURN
  CALL MapHyb_quickSort(map, 1, map%tail)
END SUBROUTINE MapHyb_sort
!!***

!!****f* ABINIT/m_MapHyb/MapHyb_quickSort
!! NAME
!!  MapHyb_quickSort
!!
!! FUNCTION
!!  sort the map with respect to the integer array
!!  with the quickSort algo
!!
!! COPYRIGHT
!!  Copyright (C) 2013-2014 ABINIT group (J. Bieder)
!!  This file is distributed under the terms of the
!!  GNU General Public License, see ~abinit/COPYING
!!  or http://www.gnu.org/copyleft/gpl.txt .
!!
!! INPUTS
!!  map=Map
!!  begin=first element to consider
!!  end=last element to consider
!!
!! OUTPUT
!!
!! SIDE EFFECTS
!!
!! NOTES
!!
!! PARENTS
!!  Will be filled automatically by the parent script
!!
!! CHILDREN
!!  Will be filled automatically by the parent script
!!
!! SOURCE

RECURSIVE SUBROUTINE MapHyb_quickSort(map, begin, end)

!Arguments ------------------------------------

!This section has been created automatically by the script Abilint (TD).
!Do not modify the following lines by hand.
#undef ABI_FUNC
#define ABI_FUNC 'MapHyb_quickSort'
!End of the abilint section

  TYPE(MapHyb), INTENT(INOUT) :: map
  INTEGER     , INTENT(IN   ) :: begin
  INTEGER     , INTENT(IN   ) :: end
!Local variables ------------------------------
  INTEGER                     :: it1
  INTEGER                     :: it2
  INTEGER                     :: pivot
  INTEGER                     :: Iswap
  DOUBLE PRECISION            :: Dswap

  pivot = map%listINT((end-begin)/2 + begin) ! not the betterchoice.... FIXME
  it1 = begin
  it2 = end
  DO WHILE (it1 .LE. it2)
    DO WHILE ( map%listINT(it1) .LT. pivot )
      it1 = it1 + 1
    END DO
    DO WHILE ( map%listINT(it2) .GT. pivot )
      it2 = it2 - 1
    END DO
    IF ( it1 .LE. it2) THEN
      Iswap = map%listINT(it1)
      Dswap = map%listDBLE(it1)
      map%listINT(it1)  = map%listINT(it2)
      map%listDBLE(it1) = map%listDBLE(it2)
      map%listINT(it2)  = Iswap
      map%listDBLE(it2) = Dswap
      it1 = it1 + 1
      it2 = it2 - 1
    END IF
  END DO
  IF ( begin < it2 ) THEN
    CALL MapHyb_quickSort(map,begin,it2)
  END IF
  !!it2= it1+1
  IF ( it1 < end ) THEN
    CALL MapHyb_quickSort(map,it1,end)
  END IF

END SUBROUTINE MapHyb_quickSort
!!***
 
!!****f* ABINIT/m_MapHyb/MapHyb_print
!! NAME
!!  MapHyb_print
!!
!! FUNCTION
!!  print the map
!!
!! COPYRIGHT
!!  Copyright (C) 2013-2014 ABINIT group (J. Bieder)
!!  This file is distributed under the terms of the
!!  GNU General Public License, see ~abinit/COPYING
!!  or http://www.gnu.org/copyleft/gpl.txt .
!!
!! INPUTS
!!  map=Map
!!  ostream=file stream
!!
!! OUTPUT
!!
!! SIDE EFFECTS
!!
!! NOTES
!!
!! PARENTS
!!  Will be filled automatically by the parent script
!!
!! CHILDREN
!!  Will be filled automatically by the parent script
!!
!! SOURCE

SUBROUTINE MapHyb_print(map,ostream)

!Arguments ------------------------------------

!This section has been created automatically by the script Abilint (TD).
!Do not modify the following lines by hand.
#undef ABI_FUNC
#define ABI_FUNC 'MapHyb_print'
!End of the abilint section

  TYPE(MapHyb)     , INTENT(IN) :: map
  INTEGER, OPTIONAL, INTENT(IN) :: ostream
!Local variables ------------------------------
  INTEGER                       :: ostream_val
  INTEGER                       :: it

  ostream_val = 6
  IF ( PRESENT(ostream) ) ostream_val = ostream
  WRITE(ostream_val,'(A,2x,A5,2x,A5)') "#","Index", "Value"
  DO it = 1, map%tail
    WRITE(ostream_val,'(3x,I5,2x,ES22.14)') map%listINT(it), map%listDBLE(it) 
  END DO
END SUBROUTINE MapHyb_print
!!***

!!****f* ABINIT/m_MapHyb/MapHyb_clear
!! NAME
!!  MapHyb_clear
!!
!! FUNCTION
!!  Clear the map
!!
!! COPYRIGHT
!!  Copyright (C) 2013-2014 ABINIT group (J. Bieder)
!!  This file is distributed under the terms of the
!!  GNU General Public License, see ~abinit/COPYING
!!  or http://www.gnu.org/copyleft/gpl.txt .
!!
!! INPUTS
!!  map=Map
!!
!! OUTPUT
!!
!! SIDE EFFECTS
!!
!! NOTES
!!
!! PARENTS
!!  Will be filled automatically by the parent script
!!
!! CHILDREN
!!  Will be filled automatically by the parent script
!!
!! SOURCE

SUBROUTINE MapHyb_clear(map)

!Arguments ------------------------------------

!This section has been created automatically by the script Abilint (TD).
!Do not modify the following lines by hand.
#undef ABI_FUNC
#define ABI_FUNC 'MapHyb_clear'
!End of the abilint section

  TYPE(MapHyb), INTENT(INOUT) :: map
  map%tail = 0 
END SUBROUTINE MapHyb_clear
!!***

!!****f* ABINIT/m_MapHyb/MapHyb_destroy
!! NAME
!!  MapHyb_destroy
!!
!! FUNCTION
!!  destroy and deallocate the map
!!
!! COPYRIGHT
!!  Copyright (C) 2013-2014 ABINIT group (J. Bieder)
!!  This file is distributed under the terms of the
!!  GNU General Public License, see ~abinit/COPYING
!!  or http://www.gnu.org/copyleft/gpl.txt .
!!
!! INPUTS
!!  map=Map
!!
!! OUTPUT
!!
!! SIDE EFFECTS
!!
!! NOTES
!!
!! PARENTS
!!  Will be filled automatically by the parent script
!!
!! CHILDREN
!!  Will be filled automatically by the parent script
!!
!! SOURCE

SUBROUTINE MapHyb_destroy(map)

!Arguments ------------------------------------

!This section has been created automatically by the script Abilint (TD).
!Do not modify the following lines by hand.
#undef ABI_FUNC
#define ABI_FUNC 'MapHyb_destroy'
!End of the abilint section

  TYPE(MapHyb), INTENT(INOUT) :: map

  FREEIF(map%listINT)
  FREEIF(map%listDBLE)

  map%tail     = 0
  map%size     = 0
END SUBROUTINE MapHyb_destroy
!!***

END MODULE m_MapHyb
!!***


