!===============================================================================
!
! vec.F90
!
!-------------------------------------------------------------------------------
!
! Copyright (C) 2006 Yoshifumi Nakamura 
!
! This file is part of BQCD -- Berlin Quantum ChromoDynamics program
!
! BQCD is free software: you can redistribute it and/or modify
! it under the terms of the GNU General Public License as published by
! the Free Software Foundation, either version 3 of the License, or
! (at your option) any later version.
!
! BQCD is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
! GNU General Public License for more details.
!
! You should have received a copy of the GNU General Public License
! along with BQCD.  If not, see <http://www.gnu.org/licenses/>.
!
!-------------------------------------------------------------------------------
# include "defs.h"

!-------------------------------------------------------------------------------
module vec

  interface
     real(8) function vec_norm2_c8(in)
     complex(8), pointer :: in(:)
     end
     real(8) function vec_norm2_c4(in)
     complex(4), pointer :: in(:)
     end

     real(8) function vec_dot_c8(x,y)
     complex(8), pointer :: x(:),y(:)
     end
     real(8) function vec_dot_c4(x,y)
     complex(4), pointer :: x(:),y(:)
     end

     complex(8) function vec_cdotc_c8(x,y)
     complex(8), pointer :: x(:),y(:)
     end
     complex(8) function vec_cdotc_c4(x,y)
     complex(4), pointer :: x(:),y(:)
     end
   end interface

end module vec
!-------------------------------------------------------------------------------
! c8
!-------------------------------------------------------------------------------
real(8) function vec_norm2_c8(in)  ! Sum_i abs(in_i)**2
  implicit none
  complex(8), pointer :: in(:)
  real(8)           :: tmp 
  integer           :: i

  tmp = ZERO
  !$omp parallel do reduction(+: tmp)
  do i = 1, size(in)
     tmp = tmp + conjg(in(i)) * in(i)
  enddo
  vec_norm2_c8 = tmp
end function vec_norm2_c8

!-------------------------------------------------------------------------------
real(8) function vec_dot_c8(x, y)  ! Sum_i [Re(x_i) * Re(y_i) + Im(x_i) * Im(y_i)]
  implicit none
  complex(8), pointer :: x(:), y(:)
  real(8)           :: tmp 
  integer           :: i

  tmp = ZERO
  !$omp parallel do reduction(+: tmp)
  do i = 1, size(x)
     tmp = tmp + y(i) * conjg(x(i))
  enddo
  vec_dot_c8 = tmp
end function vec_dot_c8
!-------------------------------------------------------------------------------
COMPLEX function vec_cdotc_c8(x, y)  ! Sum_i conjg(x_i) * y_i
  implicit none
  COMPLEX, pointer :: x(:), y(:)
  COMPLEX             :: tmp 
  integer           :: i

  tmp = ZERO
  !$omp parallel do reduction(+: tmp)
  do i = 1, size(x)
     tmp = tmp + y(i) * conjg(x(i))
  enddo
  vec_cdotc_c8 = tmp
end function vec_cdotc_c8
!-------------------------------------------------------------------------------
! c4
!-------------------------------------------------------------------------------
real(8) function vec_norm2_c4(in)  ! Sum_i abs(in_i)**2
  implicit none
  complex(4), pointer :: in(:)
  real(8)           :: tmp 
  integer           :: i

  tmp = ZERO
  !$omp parallel do reduction(+: tmp)
  do i = 1, size(in)
     tmp = tmp + conjg(in(i)) * in(i)
  enddo
  vec_norm2_c4 = tmp
end function vec_norm2_c4
!-------------------------------------------------------------------------------
real(8) function vec_dot_c4(x, y)  ! Sum_i [Re(x_i) * Re(y_i) + Im(x_i) * Im(y_i)]
  implicit none
  complex(4), pointer :: x(:), y(:)
  real(8)           :: tmp 
  integer           :: i

  tmp = ZERO
  !$omp parallel do reduction(+: tmp)
  do i = 1, size(x)
     tmp = tmp + y(i) * conjg(x(i))
  enddo
  vec_dot_c4 = tmp
end function vec_dot_c4
!-------------------------------------------------------------------------------
complex(8) function vec_cdotc_c4(x, y)  ! Sum_i conjg(x_i) * y_i
  implicit none
  complex(4), pointer :: x(:), y(:)
  complex(8)             :: tmp 
  integer           :: i

  tmp = ZERO
  !$omp parallel do reduction(+: tmp)
  do i = 1, size(x)
     tmp = tmp + y(i) * conjg(x(i))
  enddo
  vec_cdotc_c4 = tmp
end function vec_cdotc_c4
!===============================================================================
