!%f90 -*- f90 -*-
! Signatures for f2py-wrappers of FORTRAN LEVEL 1 BLAS functions.
!
! Author: Pearu Peterson
! Created: Jan-Feb 2002
! Modified: Fabian Pedregosa, 2011
!
! Implemented:
!
!   rotg, rotmg, rot, rotm
!   swap, scal, copy, axpy
!   dot, dotu, dotc
!   nrm2, asum, amax, iamax
!
! Not Implemented: NONE
!
! NOTE: Avoiding wrappers hack does not work under 64-bit Gentoo system
! with single precision routines, so they are removed.
!
! Level 1 BLAS

subroutine <prefix>rotg(a,b,c,s)
  ! Computes the parameters for a Givens rotation.
  !
  ! Given the Cartesian coordinates (a, b) of a point p, these routines return
  ! the parameters a, b, c, and s associated with the Givens rotation that zeros
  ! the y-coordinate of the point.
  !
  ! FIXME: parameters a, b are not returned.
  !
  callprotoargument <ctype>*,<ctype>*,<ctype>*,<ctype>*

  <ftype> intent(in) :: a, b
  <ftype> intent(out,out=c) :: c
  <ftype> intent(out,out=s) :: s

end subroutine <prefix>rotg

! <prefix2=s,d> <ctype2=float,double> <ftype2=real,double precision>
subroutine <prefix2>rotmg(d1,d2,x1,y1,param)
  ! Computes the parameters for a modified Givens rotation.
  !
  ! Given Cartesian coordinates (x1, y1) of an input vector, this
  ! routine compute the components of a modified Givens
  ! transformation matrix H that zeros the y-component of the
  ! resulting vector:
  !
  !    [x]     [sqrt(d1) x1]
  !    [ ] = H [           ]
  !    [0]     [sqrt(d2) y1]
  !

  callstatement (*f2py_func)(&d1,&d2,&x1,&y1,param)
  callprotoargument <ctype2>*,<ctype2>*,<ctype2>*,<ctype2>*,<ctype2>*

  <ftype2> intent(in) :: d1, d2, x1, y1
  <ftype2> intent(out), dimension(5) :: param

end subroutine <prefix2>rotmg


subroutine <tchar=s,d,cs,zd>rot(n,x,offx,incx,y,offy,incy,c,s)
  ! Applies a plane rotation with real cosine and complex sine to a
  ! pair of complex vectors and returns the modified vectors.
  !
  ! x, y are input vectors and c, s are values that define a rotation:
  !
  !                [ c        s]
  !                [           ]
  !                [-conj(s)  c]
  !
  ! where c*c + s*conjg(s) = 1.0.
  !

  callstatement (*f2py_func)(&n,x+offx,&incx,y+offy,&incy,&c,&s)
  callprotoargument int*,<ctype>*,int*,<ctype>*,int*,<ctypereal>*,<ctypereal>*

  <ftype> dimension(*),intent(in,out,copy) :: x,y
  <ftypereal> intent(in) :: c, s
  integer optional, intent(in), check(incx>0||incx<0) :: incx = 1
  integer optional, intent(in), check(incy>0||incy<0) :: incy = 1
  integer optional, intent(in), depend(x) :: offx=0
  integer optional, intent(in), depend(y) :: offy=0
  check(offx>=0 && offx<len(x)) :: offx
  check(offy>=0 && offy<len(y)) :: offy
  integer optional, intent(in), depend(x,incx,offx,y,incy,offy) :: &
       n = (len(x)-offx)/abs(incx)
  check(len(x)-offx>(n-1)*abs(incx)) :: n
  check(len(y)-offy>(n-1)*abs(incy)) :: n

end subroutine <tchar=s,d,cs,zd>rot


subroutine <prefix2>rotm(n,x,offx,incx,y,offy,incy,param)
  ! Performs rotation of points in the modified plane
  !
  ! Given two complex vectors x and y, each vector element of these vectors is
  ! replaced as follows:
  !
  !      x(i) = H*x(i) + H*y(i)
  !      y(i) = H*y(i) - H*x(i)
  !
  ! where H is a modified Givens transformation matrix whose values are stored
  ! in the param(2) through param(5) array.

  callstatement (*f2py_func)(&n,x+offx,&incx,y+offy,&incy,param)
  callprotoargument int*,<ctype2>*,int*,<ctype2>*,int*,<ctype2>*

  <ftype2> dimension(*), intent(in,out,copy) :: x, y
  <ftype2> dimension(5), intent(in) :: param
  integer optional, intent(in),check(incx>0||incx<0) :: incx = 1
  integer optional, intent(in),check(incy>0||incy<0) :: incy = 1
  integer optional, intent(in),depend(x) :: offx=0
  integer optional, intent(in),depend(y) :: offy=0
  check(offx>=0 && offx<len(x)) :: offx
  check(offy>=0 && offy<len(y)) :: offy
  integer optional, intent(in),depend(x,incx,offx,y,incy,offy) :: &
       n = (len(x)-offx)/abs(incx)
  check(len(x)-offx>(n-1)*abs(incx)) :: n
  check(len(y)-offy>(n-1)*abs(incy)) :: n

end subroutine <prefix2>rotm


subroutine <prefix>swap(n,x,offx,incx,y,offy,incy)
  ! Swap two arrays: x <-> y

  callstatement (*f2py_func)(&n,x+offx,&incx,y+offy,&incy)
  callprotoargument int*,<ctype>*,int*,<ctype>*,int*

  <ftype> dimension(*), intent(in,out) :: x, y
  integer optional, intent(in),check(incx>0||incx<0) :: incx = 1
  integer optional, intent(in),check(incy>0||incy<0) :: incy = 1
  integer optional, intent(in),depend(x) :: offx=0
  integer optional, intent(in),depend(y) :: offy=0
  check(offx>=0 && offx<len(x)) :: offx
  check(offy>=0 && offy<len(y)) :: offy
  integer optional, intent(in),depend(x,incx,offx,y,incy,offy) :: &
       n = (len(x)-offx)/abs(incx)
  check(len(x)-offx>(n-1)*abs(incx)) :: n
  check(len(y)-offy>(n-1)*abs(incy)) :: n

end subroutine <prefix>swap


subroutine <prefix>scal(n,a,x,offx,incx)
  ! Computes the product of a vector by a scalar: y = a*x

  callstatement (*f2py_func)(&n,&a,x+offx,&incx)
  callprotoargument int*,<ctype>*,<ctype>*,int*

  <ftype> intent(in):: a
  <ftype> dimension(*), intent(in,out) :: x
  integer optional, intent(in), check(incx>0||incx<0) :: incx = 1
  integer optional, intent(in), depend(x) :: offx=0
  check(offx>=0 && offx<len(x)) :: offx
  integer optional, intent(in),depend(x,incx,offx) :: n = (len(x)-offx)/abs(incx)
  check(len(x)-offx>(n-1)*abs(incx)) :: n

end subroutine <prefix>scal


subroutine <tchar=cs,zd>scal(n,a,x,offx,incx)
  ! Computes the product of a vector by a scalar, scales a complex
  ! vector by a real constant
  ! y = a*x

  callstatement (*f2py_func)(&n,&a,x+offx,&incx)
  callprotoargument int*,<float,double>*,<complex_float, complex_double>*,int*

  <real,double precision> intent(in) :: a
  <complex, double complex> dimension(*), intent(in,out,copy) :: x
  integer optional, intent(in),check(incx>0||incx<0) :: incx = 1
  integer optional, intent(in),depend(x) :: offx=0
  check(offx>=0 && offx<len(x)) :: offx
  integer optional, intent(in),depend(x,incx,offx) :: n = (len(x)-offx)/abs(incx)
  check(len(x)-offx>(n-1)*abs(incx)) :: n

end subroutine <tchar=cs,zd>scal


subroutine <prefix>copy(n,x,offx,incx,y,offy,incy)
  ! Copy y <- x

  callstatement (*f2py_func)(&n,x+offx,&incx,y+offy,&incy)
  callprotoargument int*,<ctype>*,int*,<ctype>*,int*

  <ftype> dimension(*), intent(in) :: x
  <ftype> dimension(*), intent(in,out) :: y
  integer optional, intent(in),check(incx>0||incx<0) :: incx = 1
  integer optional, intent(in),check(incy>0||incy<0) :: incy = 1
  integer optional, intent(in),depend(x) :: offx=0
  integer optional, intent(in),depend(y) :: offy=0
  check(offx>=0 && offx<len(x)) :: offx
  check(offy>=0 && offy<len(y)) :: offy
  integer optional, intent(in),depend(x,incx,offx,y,incy,offy) :: &
       n = (len(x)-offx)/abs(incx)
  check(len(x)-offx>(n-1)*abs(incx)) :: n
  check(len(y)-offy>(n-1)*abs(incy)) :: n

end subroutine <prefix>copy


subroutine <prefix>axpy(n,a,x,offx,incx,y,offy,incy)
  ! Calculate z = a*x+y, where a is scalar.

  callstatement (*f2py_func)(&n,&a,x+offx,&incx,y+offy,&incy)
  callprotoargument int*,<ctype>*,<ctype>*,int*,<ctype>*,int*

  <ftype> dimension(*), intent(in) :: x
  <ftype> dimension(*), intent(in,out,out=z) :: y
  <ftype> optional, intent(in):: a=<1.0,\0,(1.0\,0.0),\2>
  integer optional, intent(in),check(incx>0||incx<0) :: incx = 1
  integer optional, intent(in),check(incy>0||incy<0) :: incy = 1
  integer optional, intent(in),depend(x) :: offx=0
  integer optional, intent(in),depend(y) :: offy=0
  check(offx>=0 && offx<len(x)) :: offx
  check(offy>=0 && offy<len(y)) :: offy
  integer optional, intent(in),depend(x,incx,offx,y,incy,offy) :: &
       n = (len(x)-offx)/abs(incx)
  check(len(x)-offx>(n-1)*abs(incx)) :: n
  check(len(y)-offy>(n-1)*abs(incy)) :: n

end subroutine <prefix>axpy


function <prefix2>dot(n,x,offx,incx,y,offy,incy) result (xy)
  ! Computes a vector-vector dot product.

  callstatement (*f2py_func)(&<prefix2>dot,&n,x+offx,&incx,y+offy,&incy)
  callprotoargument <ctype2>*,int*,<ctype2>*,int*,<ctype2>*,int*

  <ftype2> dimension(*), intent(in) :: x
  <ftype2> dimension(*), intent(in) :: y
  <ftype2> <prefix2>dot,xy
  integer optional, intent(in),check(incx>0||incx<0) :: incx = 1
  integer optional, intent(in),check(incy>0||incy<0) :: incy = 1
  integer optional, intent(in),depend(x) :: offx=0
  integer optional, intent(in),depend(y) :: offy=0
  check(offx>=0 && offx<len(x)) :: offx
  check(offy>=0 && offy<len(y)) :: offy
  integer optional, intent(in),depend(x,incx,offx,y,incy,offy) :: &
       n = (len(x)-offx)/abs(incx)
  check(len(x)-offx>(n-1)*abs(incx)) :: n
  check(len(y)-offy>(n-1)*abs(incy)) :: n

end function <prefix2>dot



! <prefix2c=c,z> <ftype2c=complex,double complex> <ctype2c=complex_float,complex_double>
subroutine <prefix2c>dotu(xy,n,x,offx,incx,y,offy,incy)

  <ftype2c> intent(out) :: xy
  fortranname w<prefix2c>dotu

  callstatement (*f2py_func)(&xy,&n,x+offx,&incx,y+offy,&incy)
  callprotoargument <ctype2c>*,int*,<ctype2c>*,int*,<ctype2c>*,int*

  <ftype2c> dimension(*),intent(in) :: x
  <ftype2c> dimension(*),intent(in) :: y

  integer optional, intent(in),check(incx>0||incx<0) :: incx = 1
  integer optional, intent(in),check(incy>0||incy<0) :: incy = 1

  integer optional,intent(in),depend(x) :: offx=0
  integer optional,intent(in),depend(y) :: offy=0
  check(offx>=0 && offx<len(x)) :: offx
  check(offy>=0 && offy<len(y)) :: offy

  integer optional,intent(in),depend(x,incx,offx,y,incy,offy) &
       :: n = (len(x)-offx)/abs(incx)
  check(len(x)-offx>(n-1)*abs(incx)) :: n
  check(len(y)-offy>(n-1)*abs(incy)) :: n

end subroutine <prefix2c>dotu


subroutine <prefix2c>dotc(xy,n,x,offx,incx,y,offy,incy)

  <ftype2c> intent (out) :: xy
  fortranname w<prefix2c>dotc

  callstatement (*f2py_func)(&xy,&n,x+offx,&incx,y+offy,&incy)
  callprotoargument <ctype2c>*,int*,<ctype2c>*,int*,<ctype2c>*,int*

  <ftype2c> dimension(*),intent(in) :: x
  <ftype2c> dimension(*),intent(in) :: y

  integer optional, intent(in),check(incx>0||incx<0) :: incx = 1
  integer optional, intent(in),check(incy>0||incy<0) :: incy = 1

  integer optional,intent(in),depend(x) :: offx=0
  integer optional,intent(in),depend(y) :: offy=0
  check(offx>=0 && offx<len(x)) :: offx
  check(offy>=0 && offy<len(y)) :: offy

  integer optional,intent(in),depend(x,incx,offx,y,incy,offy) :: n = (len(x)-offx)/abs(incx)
  check(len(x)-offx>(n-1)*abs(incx)) :: n
  check(len(y)-offy>(n-1)*abs(incy)) :: n

end subroutine <prefix2c>dotc

! <prefix3=s,d,sc,dz>
function <prefix3>nrm2(n,x,offx,incx) result(n2)

  <ftypereal> <prefix3>nrm2, n2

  callstatement (*f2py_func)(&<prefix3>nrm2, &n,x+offx,&incx)
  callprotoargument <ctypereal>*,int*,<ctype>*,int*

  <ftype> dimension(*),intent(in) :: x

  integer optional, intent(in),check(incx>0||incx<0) :: incx = 1

  integer optional,intent(in),depend(x) :: offx=0
  check(offx>=0 && offx<len(x)) :: offx

  integer optional,intent(in),depend(x,incx,offx) :: n = (len(x)-offx)/abs(incx)
  check(len(x)-offx>(n-1)*abs(incx)) :: n

end function <prefix3>nrm2


function <tchar=s,d,sc,dz>asum(n,x,offx,incx) result (s)
  ! Computes the sum of magnitudes of the vector elements

  callstatement (*f2py_func)(&<tchar=s,d,sc,dz>asum,&n,x+offx,&incx)
  callprotoargument <ctypereal>*,int*,<ctype>*,int*

  <ftype> dimension(*), intent(in) :: x
  <ftypereal> <tchar=s,d,sc,dz>asum,s
  integer optional, intent(in), check(incx>0||incx<0) :: incx = 1
  integer optional, intent(in), depend(x) :: offx=0
  check(offx>=0 && offx<len(x)) :: offx
  integer optional, intent(in),depend(x,incx,offx) :: n = (len(x)-offx)/abs(incx)
  check(len(x)-offx>(n-1)*abs(incx)) :: n

end function <tchar=s,d,sc,dz>asum


function i<prefix>amax(n,x,offx,incx) result(k)
  ! Finds the index of the element with maximum absolute value.

  callstatement i<prefix>amax_return_value = (*f2py_func)(&n,x+offx,&incx) - 1
  callprotoargument int*,<ctype>*,int*

  ! This is to avoid Fortran wrappers.
  integer i<prefix>amax,k
  fortranname F_FUNC(i<prefix>amax,I<S,D,C,Z>AMAX)
  intent(c) i<prefix>amax
  <ftype> dimension(*), intent(in) :: x
  integer optional, intent(in), check(incx>0||incx<0) :: incx = 1
  integer optional, intent(in), depend(x) :: offx=0
  check(offx>=0 && offx<len(x)) :: offx
  integer optional, intent(in),depend(x,incx,offx) :: n = (len(x)-offx)/abs(incx)
  check(len(x)-offx>(n-1)*abs(incx)) :: n

end function i<prefix>amax

