#if defined HAVE_CONFIG_H
#include "config.h"
#endif
!{\src2tex{textfont=tt}}
!!****m* ABINIT/m_MatrixHyb
!! NAME
!!  m_MatrixHyb
!! 
!! FUNCTION 
!!  matrix 
!!
!! 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_MatrixHyb
USE m_Global
IMPLICIT NONE

!!***

PRIVATE

!!****t* m_MatrixHyb/MatrixHyb
!! NAME
!!  MatrixHyb
!!
!! 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 :: MatrixHyb
  INTEGER _PRIVATE :: size
  INTEGER          :: tail
  INTEGER _PRIVATE :: iTech = -1
  INTEGER _PRIVATE :: Wmax
  DOUBLE PRECISION, ALLOCATABLE, DIMENSION(:,:)           :: mat
  INTEGER         , ALLOCATABLE, DIMENSION(:,:)           :: mat_tau
  COMPLEX(KIND=8) , ALLOCATABLE, DIMENSION(:,:,:)         :: mat_omega
END TYPE MatrixHyb
!!***

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

PUBLIC  :: MatrixHyb_init
PUBLIC  :: MatrixHyb_setSize
PRIVATE :: MatrixHyb_enlarge
PUBLIC  :: MatrixHyb_clear
PUBLIC  :: MatrixHyb_assign
PUBLIC  :: MatrixHyb_inverse
PRIVATE :: MatrixHyb_LU
PUBLIC  :: MatrixHyb_getDet
PUBLIC  :: MatrixHyb_print
PUBLIC  :: MatrixHyb_destroy

CONTAINS
!!***

!!****f* ABINIT/m_MatrixHyb/MatrixHyb_init
!! NAME
!!  MatrixHyb_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
!!  matrix_1=matrix
!!  iTech=DO NOT USE => BUG
!!  size=memory size for initialization
!!  Wmax=maximum frequency number
!!
!! OUTPUT
!!
!! SIDE EFFECTS
!!
!! NOTES
!!
!! PARENTS
!!  Will be filled automatically by the parent script
!!
!! CHILDREN
!!  Will be filled automatically by the parent script
!!
!! SOURCE

SUBROUTINE MatrixHyb_init(matrix_1, iTech, size, Wmax)

!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 'MatrixHyb_init'
!End of the abilint section

  TYPE(MatrixHyb)     , INTENT(INOUT) :: matrix_1
  INTEGER             , INTENT(IN   ) :: iTech
  INTEGER, OPTIONAL, INTENT(IN   ) :: size
  INTEGER, OPTIONAL, INTENT(IN   ) :: Wmax
!Local variables ------------------------------
  INTEGER                          :: size_val

  size_val = Global_SIZE
  IF ( PRESENT(size) ) size_val = size
  matrix_1%size = size_val
  FREEIF(matrix_1%mat)
  MALLOC(matrix_1%mat,(1:size_val,1:size_val))
  matrix_1%tail  = 0 
  matrix_1%mat   = 0.d0
  matrix_1%iTech = iTech
  SELECT CASE(matrix_1%iTech)
  CASE (GREENHYB_TAU)
    FREEIF(matrix_1%mat_tau)
    MALLOC(matrix_1%mat_tau,(1:size_val,1:size_val))
  CASE (GREENHYB_OMEGA)
    IF ( PRESENT(Wmax) .AND. Wmax .GT. 0 ) THEN
      FREEIF(matrix_1%mat_omega)
      MALLOC(matrix_1%mat_omega,(1:Wmax,1:size_val,1:size_val))
      matrix_1%Wmax=Wmax
    ELSE
      CALL ERROR("MatrixHyb_init : Missing argument Wmax for measurement in omega")
    END IF
  CASE DEFAULT
      CALL WARNALL("MatrixHyb_init : Wrong input argument iTech")
  END SELECT
END SUBROUTINE MatrixHyb_init
!!***

!!****f* ABINIT/m_MatrixHyb/MatrixHyb_setSize
!! NAME
!!  MatrixHyb_setSize
!!
!! FUNCTION
!!  impose size of the matrix
!!
!! 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
!!  matrix_1=matrix
!!  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 MatrixHyb_setSize(matrix_1,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 'MatrixHyb_setSize'
!End of the abilint section

  TYPE(MatrixHyb), INTENT(INOUT) :: matrix_1
  INTEGER        , INTENT(IN   ) :: new_tail
!Local variables ------------------------------
  INTEGER                        :: size

  IF ( .NOT. ALLOCATED(matrix_1%mat) ) &
    CALL MatrixHyb_init(matrix_1,matrix_1%iTech,Wmax=matrix_1%Wmax)
  size = matrix_1%size
  IF( new_tail .GT. size ) THEN
    CALL MatrixHyb_enlarge(matrix_1, MAX(Global_SIZE,new_tail-size))
  END IF
  matrix_1%tail = new_tail
END SUBROUTINE MatrixHyb_setSize  
!!***

!!****f* ABINIT/m_MatrixHyb/MatrixHyb_enlarge
!! NAME
!!  MatrixHyb_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
!!  matrix_1=matrix
!!  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 MatrixHyb_enlarge(matrix_1, 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 'MatrixHyb_enlarge'
!End of the abilint section

  TYPE(MatrixHyb)     , INTENT(INOUT)          :: matrix_1
  INTEGER, OPTIONAL, INTENT(IN   )          :: size
!Local variables ------------------------------
  INTEGER                                   :: width
  INTEGER                                   :: tail
  DOUBLE PRECISION, ALLOCATABLE, DIMENSION(:,:) :: matrix_temp 
  INTEGER         , ALLOCATABLE, DIMENSION(:,:) :: matrix_temp_tau
  COMPLEX(KIND=8) , ALLOCATABLE, DIMENSION(:,:,:) :: matrix_temp_omega
  INTEGER                                   :: size_val

  IF ( ALLOCATED(matrix_1%mat) ) THEN
    FREEIF(matrix_temp)
    FREEIF(matrix_temp_tau)
    width = matrix_1%size
    tail  = matrix_1%tail 
    size_val = width
    IF ( PRESENT(size) ) size_val = size 
    MALLOC(matrix_temp,(1:tail,1:tail))
    matrix_temp(1:tail,1:tail) = matrix_1%mat(1:tail,1:tail)
    FREE(matrix_1%mat)
    matrix_1%size = width + size_val
    MALLOC(matrix_1%mat,(1:matrix_1%size,1:matrix_1%size))
    matrix_1%mat(1:tail,1:tail) = matrix_temp(1:tail,1:tail)
    FREE(matrix_temp)
    SELECT CASE(matrix_1%iTech)
    CASE (GREENHYB_TAU)
      MALLOC(matrix_temp_tau,(1:tail,1:tail))
      matrix_temp_tau(1:tail,1:tail) = matrix_1%mat_tau(1:tail,1:tail)
      FREE(matrix_1%mat_tau)
      MALLOC(matrix_1%mat_tau,(1:matrix_1%size,1:matrix_1%size))
      matrix_1%mat_tau(1:tail,1:tail) = matrix_temp_tau(1:tail,1:tail)
      FREE(matrix_temp_tau)
    CASE (GREENHYB_OMEGA)
      MALLOC(matrix_temp_omega,(1:matrix_1%Wmax,1:tail,1:tail))
      matrix_temp_omega(1:matrix_1%Wmax,1:tail,1:tail) = matrix_1%mat_omega(1:matrix_1%Wmax,1:tail,1:tail)
      FREE(matrix_1%mat_omega)
      MALLOC(matrix_1%mat_omega,(1:matrix_1%Wmax,1:matrix_1%size,1:matrix_1%size))
      matrix_1%mat_omega(1:matrix_1%Wmax,1:tail,1:tail) = matrix_temp_omega(1:matrix_1%Wmax,1:tail,1:tail)
      FREE(matrix_temp_omega)
    END SELECT
  ELSE
    CALL MatrixHyb_init(matrix_1, matrix_1%iTech, size=Global_SIZE, Wmax=matrix_1%Wmax)
  END IF
END SUBROUTINE MatrixHyb_enlarge
!!***

!!****f* ABINIT/m_MatrixHyb/MatrixHyb_clear
!! NAME
!!  MatrixHyb_clear
!!
!! FUNCTION
!!  Clear matrix
!!
!! 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
!!  matrix_1=matrix
!!
!! OUTPUT
!!
!! SIDE EFFECTS
!!
!! NOTES
!!
!! PARENTS
!!  Will be filled automatically by the parent script
!!
!! CHILDREN
!!  Will be filled automatically by the parent script
!!
!! SOURCE

SUBROUTINE MatrixHyb_clear(matrix_1)

!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 'MatrixHyb_clear'
!End of the abilint section

  TYPE(MatrixHyb), INTENT(INOUT) :: matrix_1
  matrix_1%tail = 0 
END SUBROUTINE MatrixHyb_clear
!!***

!!****f* ABINIT/m_MatrixHyb/MatrixHyb_assign
!! NAME
!!  MatrixHyb_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
!!  matrix_1=Matrix 1
!!  matrix_2=Matrix 2
!!
!! OUTPUT
!!
!! SIDE EFFECTS
!!
!! NOTES
!!
!! PARENTS
!!  Will be filled automatically by the parent script
!!
!! CHILDREN
!!  Will be filled automatically by the parent script
!!
!! SOURCE

SUBROUTINE MatrixHyb_assign(matrix_1, matrix_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 'MatrixHyb_assign'
!End of the abilint section

  TYPE(MatrixHyb), INTENT(INOUT) :: matrix_1
  TYPE(MatrixHyb), INTENT(IN   ) :: matrix_2
!Local variables ------------------------------
  INTEGER                        :: tail

  tail = matrix_2%tail
  CALL MatrixHyb_setSize(matrix_1, tail)
  matrix_1%mat(1:tail,1:tail) = matrix_2%mat(1:tail,1:tail)
  IF ( matrix_1%iTech .NE. matrix_2%iTech ) & 
    CALL ERROR("MatrixHyb_assign : not compatible matrices")
  SELECT CASE(matrix_1%iTech)
  CASE (GREENHYB_TAU)
    matrix_1%mat_tau(1:tail,1:tail) = matrix_2%mat_tau(1:tail,1:tail)
  CASE (GREENHYB_OMEGA)
    IF ( matrix_1%Wmax .NE. matrix_2%Wmax ) &
      CALL ERROR("MatrixHyb_assig : different numbers of omega")
    matrix_1%mat_omega(1:matrix_1%Wmax,1:tail,1:tail) = &
    matrix_2%mat_omega(1:matrix_1%Wmax,1:tail,1:tail)
  END SELECT

END SUBROUTINE MatrixHyb_assign
!!***

!!****f* ABINIT/m_MatrixHyb/MatrixHyb_inverse
!! NAME
!!  MatrixHyb_inverse
!!
!! FUNCTION
!!  inverse the  matrix and compute the determinant
!!
!! 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
!!  matrix_1=matrix
!!
!! OUTPUT
!!  determinant=determinant of the matrix before inversion
!!
!! SIDE EFFECTS
!!
!! NOTES
!!
!! PARENTS
!!  Will be filled automatically by the parent script
!!
!! CHILDREN
!!  Will be filled automatically by the parent script
!!
!! SOURCE

SUBROUTINE MatrixHyb_inverse(matrix_1,determinant)

!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 'MatrixHyb_inverse'
!End of the abilint section

  TYPE(MatrixHyb), INTENT(INOUT) :: matrix_1
  DOUBLE PRECISION, OPTIONAL, INTENT(OUT) :: determinant
  DOUBLE PRECISION, ALLOCATABLE, DIMENSION(:,:) :: invMatrix
!Local variables ------------------------------
  !DOUBLE PRECISION :: reste
  INTEGER :: ligne
  INTEGER :: ligne_virtuelle
  INTEGER :: colonne
  INTEGER :: sys
  INTEGER :: sys_vir
  INTEGER :: tail
  INTEGER, DIMENSION(:), ALLOCATABLE :: pivot 
  DOUBLE PRECISION :: det

  tail = matrix_1%tail
  IF ( tail .EQ. 0 ) THEN
    IF ( PRESENT(determinant) ) determinant = 1.d0
    RETURN
  END IF

  MALLOC(invMatrix,(1:tail,1:tail))

  FREEIF(pivot)
  MALLOC(pivot,(1:tail))

  CALL MatrixHyb_LU(matrix_1, pivot=pivot, determinant=det)

  !det = 1.d0
  DO sys = 1, tail
    sys_vir = pivot(sys)
!!    DO ligne=1,tail
!!      ligne_virtuelle = pivot(ligne)
!!      reste = 0.d0
!!      DO colonne = 1, ligne-1
!!        reste = reste + matrix_1%mat(ligne_virtuelle,colonne)*invMatrix%mat(colonne,sys_vir)
!!      END DO
!!      IF ( ligne .EQ. sys ) THEN
!!        invMatrix%mat(ligne,sys_vir) = 1.d0 - reste
!!      ELSE
!!        invMatrix%mat(ligne,sys_vir) = 0.d0 - reste
!!      END IF
!!    END DO
!!    
!!    DO ligne = tail, 1, -1
!!      ligne_virtuelle=pivot(ligne)
!!      reste = 0.d0
!!        DO colonne = ligne+1, tail
!!          reste= reste + matrix_1%mat(ligne_virtuelle,colonne)*invMatrix%mat(colonne,sys_vir)
!!        END DO
!!        invMatrix%mat(ligne, sys_vir) = (invMatrix%mat(ligne, sys_vir)-reste)/matrix_1%mat(ligne_virtuelle,ligne)
!!    END DO
    !det = det*matrix_1%mat(sys_vir,sys)
    invMatrix(:,sys_vir) = 0.d0
    invMatrix(sys,sys_vir) = 1.d0
    DO colonne = 1, tail-1
      DO ligne=colonne+1,tail
        ligne_virtuelle = pivot(ligne)
        invMatrix(ligne, sys_vir) = invMatrix(ligne,sys_vir) &
                                                - matrix_1%mat(ligne_virtuelle,colonne)  &
                                                * invMatrix(colonne,sys_vir)
      END DO
    END DO

    DO colonne = tail, 1, -1
      invMatrix(colonne, sys_vir) = invMatrix(colonne, sys_vir) / matrix_1%mat(pivot(colonne),colonne)
      DO ligne = 1, colonne-1
        ligne_virtuelle = pivot(ligne)
        invMatrix(ligne, sys_vir) = invMatrix(ligne,sys_vir) &
                                                 - matrix_1%mat(ligne_virtuelle,colonne) &
                                                 * invMatrix(colonne, sys_vir)
      END DO
    END DO

  END DO
  FREE(pivot)
  matrix_1%mat(1:tail,1:tail) = invMatrix(1:tail,1:tail)
  IF ( PRESENT(determinant) ) THEN
    determinant = det
  END IF
  FREE(invMatrix)
END SUBROUTINE MatrixHyb_inverse
!!***

!!****f* ABINIT/m_MatrixHyb/MatrixHyb_LU
!! NAME
!!  MatrixHyb_LU
!!
!! FUNCTION
!!  LU decomposition
!!
!! 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
!!  mat_a=matrix
!!
!! OUTPUT
!!  pivot=gauss pivot
!!  determinant=determinant of the matrix
!!
!! SIDE EFFECTS
!!
!! NOTES
!!
!! PARENTS
!!  Will be filled automatically by the parent script
!!
!! CHILDREN
!!  Will be filled automatically by the parent script
!!
!! SOURCE

SUBROUTINE MatrixHyb_LU(mat_a,pivot,determinant)

!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 'MatrixHyb_LU'
!End of the abilint section

  TYPE(MatrixHyb), INTENT(INOUT) :: mat_a
  INTEGER, DIMENSION(:), ALLOCATABLE, OPTIONAL, INTENT(INOUT) :: pivot
  DOUBLE PRECISION, OPTIONAL, INTENT(OUT) :: determinant
!Local variables ------------------------------
  INTEGER :: ligne
  INTEGER :: colonne 
  INTEGER :: colonne_de_1_ligne
  INTEGER :: max_ind_lig
  INTEGER :: ligne_virtuelle
  INTEGER :: tail
  INTEGER, DIMENSION(:), ALLOCATABLE :: pivot_tmp
  DOUBLE PRECISION :: max_col
  DOUBLE PRECISION :: inverse_pivot
  DOUBLE PRECISION :: coef
  DOUBLE PRECISION :: det
  DOUBLE PRECISION, DIMENSION(:,:), ALLOCATABLE :: mat_tmp

  tail = mat_a%tail
  det = 1.d0
  FREEIF(pivot_tmp)
  MALLOC(pivot_tmp,(1:tail))

  DO ligne=1, tail
    pivot_tmp(ligne)=ligne
  END DO

  MALLOC(mat_tmp,(1:tail,1:tail))
  mat_tmp(1:tail,1:tail) = mat_a%mat(1:tail,1:tail)
  DO colonne = 1, tail-1 
    max_col = ABS(mat_tmp(pivot_tmp(colonne),colonne))
    max_ind_lig = colonne

    DO ligne = colonne+1, tail 
      ligne_virtuelle = pivot_tmp(ligne)
      IF ( ABS( mat_tmp(ligne_virtuelle,colonne)).GT.max_col) then
        max_col = ABS(mat_tmp(ligne_virtuelle,colonne))
        max_ind_lig = ligne
      ENDIF
    END DO

    ligne              = pivot_tmp(colonne) 
    pivot_tmp(colonne)     = pivot_tmp(max_ind_lig)
    pivot_tmp(max_ind_lig) = ligne
    IF ( pivot_tmp(colonne) .NE. pivot_tmp(max_ind_lig) ) det = det * (-1.d0)
    inverse_pivot=1.d0 / mat_tmp(pivot_tmp(colonne),colonne)
    det = det * mat_tmp(pivot_tmp(colonne),colonne)
    DO ligne = colonne+1, tail 
      ligne_virtuelle = pivot_tmp(ligne)
      coef = mat_tmp(ligne_virtuelle,colonne)*inverse_pivot
      mat_tmp(ligne_virtuelle,colonne) = coef
      DO colonne_de_1_ligne = colonne+1, tail 
        mat_tmp(ligne_virtuelle,colonne_de_1_ligne)= mat_tmp(ligne_virtuelle,colonne_de_1_ligne)&
                                         -coef * mat_tmp(pivot_tmp(colonne) ,colonne_de_1_ligne)
      END DO
    END DO
  END DO
  det = det * mat_tmp(pivot_tmp(tail),tail)
  IF ( PRESENT(determinant) ) &
    determinant = det
  IF ( PRESENT(pivot) ) THEN
    mat_a%mat(1:tail,1:tail) = mat_tmp(1:tail,1:tail)
    IF ( ALLOCATED(pivot) .AND. SIZE(pivot) .NE. tail ) THEN
      FREE(pivot)
      MALLOC(pivot,(1:tail))
    ELSE IF ( .NOT. ALLOCATED(pivot) ) THEN
      MALLOC(pivot,(1:tail))
    END IF
    pivot(1:tail)=pivot_tmp(1:tail)
  END IF
  FREE(mat_tmp)
  FREE(pivot_tmp)
END SUBROUTINE MatrixHyb_LU
!!***

!!****f* ABINIT/m_MatrixHyb/MatrixHyb_getDet
!! NAME
!!  MatrixHyb_getDet
!!
!! FUNCTION
!!  Just get the determinant 
!!
!! 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
!!  matrix_a=matrix
!!
!! OUTPUT
!!  det=determinant
!!
!! SIDE EFFECTS
!!
!! NOTES
!!
!! PARENTS
!!  Will be filled automatically by the parent script
!!
!! CHILDREN
!!  Will be filled automatically by the parent script
!!
!! SOURCE

SUBROUTINE MatrixHyb_getDet(matrix_a,det)

!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 'MatrixHyb_getDet'
!End of the abilint section

  TYPE(MatrixHyb) , INTENT(INOUT) :: matrix_a
  DOUBLE PRECISION, INTENT(  OUT) :: det

  IF ( matrix_a%tail .EQ. 0 ) THEN
    det = 1.d0
    RETURN
  END IF
  CALL MatrixHyb_LU(matrix_a, determinant=det)
END SUBROUTINE MatrixHyb_getDet
!!***

!!****f* ABINIT/m_MatrixHyb/MatrixHyb_print
!! NAME
!!  MatrixHyb_print
!!
!! FUNCTION
!!  print Matrix
!!
!! 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
!!  matrix_1=Matrix
!!  ostream=file stream
!!  opt_print=0 mat
!!            1 mat_tau
!!            2 both
!!
!! OUTPUT
!!
!! SIDE EFFECTS
!!
!! NOTES
!!
!! PARENTS
!!  Will be filled automatically by the parent script
!!
!! CHILDREN
!!  Will be filled automatically by the parent script
!!
!! SOURCE

SUBROUTINE MatrixHyb_print(matrix_1,ostream,opt_print)

!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 'MatrixHyb_print'
!End of the abilint section

  TYPE(MatrixHyb), INTENT(IN) :: matrix_1
  INTEGER, OPTIONAL, INTENT(IN) :: ostream
  INTEGER, OPTIONAL, INTENT(IN) :: opt_print
!Local variables ------------------------------
  INTEGER                       :: ostream_val
  INTEGER                       :: opt_val
  INTEGER                       :: it1
  INTEGER                       :: it2
  CHARACTER(LEN=4 )             :: size
  CHARACTER(LEN=22)             :: string

  ostream_val = 6
  opt_val=0
  IF ( PRESENT(ostream) ) ostream_val = ostream
  IF ( PRESENT(opt_print) ) opt_val = opt_print
  WRITE(size,'(I4)') matrix_1%tail
  IF ( MOD(opt_val,2) .EQ. 0 ) THEN
    string ='(1x,A,1x,'//TRIM(ADJUSTL(size))//'(ES10.2,1x),A)'
    WRITE(ostream_val,'(A)') "["
    DO it1 = 1, matrix_1%tail
      WRITE(ostream_val,string) "[",(/ (matrix_1%mat(it1,it2),it2=1,matrix_1%tail)  /)," ]"
    END DO
    WRITE(ostream_val,'(A)') "]"
  END IF  
  IF ( opt_val .GE.1 ) THEN
    string ='(1x,A,1x,'//TRIM(ADJUSTL(size))//'(I4,1x),A)'
    WRITE(ostream_val,'(A)') "["
    DO it1 = 1, matrix_1%tail
      WRITE(ostream_val,string) "[",(/ (matrix_1%mat_tau(it1,it2),it2=1,matrix_1%tail)  /),"]"
    END DO
    WRITE(ostream_val,'(A)') "]"
  END IF
END SUBROUTINE MatrixHyb_print
!!***

!!****f* ABINIT/m_MatrixHyb/MatrixHyb_destroy
!! NAME
!!  MatrixHyb_destroy
!!
!! FUNCTION
!!  Destroy
!!
!! 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
!!  matrix_1=Matrix
!!
!! OUTPUT
!!
!! SIDE EFFECTS
!!
!! NOTES
!!
!! PARENTS
!!  Will be filled automatically by the parent script
!!
!! CHILDREN
!!  Will be filled automatically by the parent script
!!
!! SOURCE

SUBROUTINE MatrixHyb_destroy(matrix_1)

!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 'MatrixHyb_destroy'
!End of the abilint section

  TYPE(MatrixHyb), INTENT(INOUT) :: matrix_1

  FREEIF(matrix_1%mat)
  SELECT CASE(matrix_1%iTech)
  CASE (GREENHYB_TAU)
    FREEIF(matrix_1%mat_tau)
  CASE (GREENHYB_OMEGA)
    FREEIF(matrix_1%mat_omega)
  END SELECT

  matrix_1%tail     = 0
  matrix_1%size     = 0
  matrix_1%iTech    = -1
END SUBROUTINE MatrixHyb_destroy
!!***

END MODULE m_MatrixHyb
!!***

