#? * LAPACK: Miscellaneous Functions
;;.AUTHOR Fu Jie Huang, Yann LeCun
;; This provides a complete interface to the FORTRAN LAPACK
;; library of low-level linear algebra functions.

(libload "lapack-config")


;; Check if we can short-circuit by just mod-loading the object file
(let* ((dhc-make-lushflags (concat dhc-make-lushflags lapack-cflags))
       (objfile (dhc-make-test ())) )
  (when objfile
    (mod-load objfile)
    (mapcar mod-load (append lapack-liblapack lapack-libfortran))
    (exit) ) )


(de lapack-x-dummy () (cheader "typedef int int_func();") ())

;;interface generated from LAPACK Fortran files automatically
;;Fu Jie Huang, 2002

#? (icmax1 <n>  <cx>  <incx>  )
;;.VP
;;*  Purpose
;;*  =======
;;*
;;*  ICMAX1 finds the index of the element whose real part has maximum
;;*  absolute value.
;;*
;;*  Based on ICAMAX from Level 1 BLAS.
;;*  The change is to use the 'genuine' absolute value.
;;*
;;*  Contributed by Nick Higham for use with CLACON.
;;*
;;*  Arguments
;;*  =========
;;*
;;*  N       (input) INTEGER
;;*          The number of elements in the vector CX.
;;*
;;*  CX      (input) COMPLEX array, dimension (N)
;;*          The vector whose elements will be summed.
;;*
;;*  INCX    (input) INTEGER
;;*          The spacing between successive values of CX.  INCX >= 1.
;;*
;;* =====================================================================
;;*
;;*     .. Local Scalars ..
;;*  =====================================================================

(de icmax1 (n  cx  incx  )
	((-idx0- (-int-)) n )
	((-idx2- (-float-)) cx )
	((-idx0- (-int-)) incx )
	(let ((rval 0))
	#{ $rval=icmax1_(IDX_PTR($n,int), IDX_PTR($cx,float), IDX_PTR($incx,int)) #} rval))


;;interface generated from LAPACK Fortran files automatically
;;Fu Jie Huang, 2002

#? (ieeeck <ispec>  <zero>  <one>  )
;;.VP
;;*  Purpose
;;*  =======
;;*
;;*  IEEECK is called from the ILAENV to verify that Infinity and
;;*  possibly NaN arithmetic is safe (i.e. will not trap).
;;*
;;*  Arguments
;;*  =========
;;*
;;*  ISPEC   (input) INTEGER
;;*          Specifies whether to test just for inifinity arithmetic
;;*          or whether to test for infinity and NaN arithmetic.
;;*          = 0: Verify infinity arithmetic only.
;;*          = 1: Verify infinity and NaN arithmetic.
;;*
;;*  ZERO    (input) REAL
;;*          Must contain the value 0.0
;;*          This is passed to prevent the compiler from optimizing
;;*          away this code.
;;*
;;*  ONE     (input) REAL
;;*          Must contain the value 1.0
;;*          This is passed to prevent the compiler from optimizing
;;*          away this code.
;;*
;;*  RETURN VALUE:  INTEGER
;;*          = 0:  Arithmetic failed to produce the correct answers
;;*          = 1:  Arithmetic produced the correct answers
;;*
;;*     .. Local Scalars ..
;;*  =====================================================================

(de ieeeck (ispec  zero  one  )
	((-idx0- (-int-)) ispec )
	((-idx0- (-float-)) zero )
	((-idx0- (-float-)) one )
	(let ((rval 0))
	#{ $rval=ieeeck_(IDX_PTR($ispec,int), IDX_PTR($zero,float), IDX_PTR($one,float)) #} rval))


;;interface generated from LAPACK Fortran files automatically
;;Fu Jie Huang, 2002

#? (ilaenv <ispec>  <name>  <opts>  <n1>  <n2>  <n3>  <n4>  )
;;.VP
;;*  Purpose
;;*  =======
;;*
;;*  ILAENV is called from the LAPACK routines to choose problem-dependent
;;*  parameters for the local environment.  See ISPEC for a description of
;;*  the parameters.
;;*
;;*  This version provides a set of parameters which should give good,
;;*  but not optimal, performance on many of the currently available
;;*  computers.  Users are encouraged to modify this subroutine to set
;;*  the tuning parameters for their particular machine using the option
;;*  and problem size information in the arguments.
;;*
;;*  This routine will not function correctly if it is converted to all
;;*  lower case.  Converting it to all upper case is allowed.
;;*
;;*  Arguments
;;*  =========
;;*
;;*  ISPEC   (input) INTEGER
;;*          Specifies the parameter to be returned as the value of
;;*          ILAENV.
;;*          = 1: the optimal blocksize; if this value is 1, an unblocked
;;*               algorithm will give the best performance.
;;*          = 2: the minimum block size for which the block routine
;;*               should be used; if the usable block size is less than
;;*               this value, an unblocked routine should be used.
;;*          = 3: the crossover point (in a block routine, for N less
;;*               than this value, an unblocked routine should be used)
;;*          = 4: the number of shifts, used in the nonsymmetric
;;*               eigenvalue routines
;;*          = 5: the minimum column dimension for blocking to be used;
;;*               rectangular blocks must have dimension at least k by m,
;;*               where k is given by ILAENV(2,...) and m by ILAENV(5,...)
;;*          = 6: the crossover point for the SVD (when reducing an m by n
;;*               matrix to bidiagonal form, if max(m,n)/min(m,n) exceeds
;;*               this value, a QR factorization is used first to reduce
;;*               the matrix to a triangular form.)
;;*          = 7: the number of processors
;;*          = 8: the crossover point for the multishift QR and QZ methods
;;*               for nonsymmetric eigenvalue problems.
;;*          = 9: maximum size of the subproblems at the bottom of the
;;*               computation tree in the divide-and-conquer algorithm
;;*               (used by xGELSD and xGESDD)
;;*          =10: ieee NaN arithmetic can be trusted not to trap
;;*          =11: infinity arithmetic can be trusted not to trap
;;*
;;*  NAME    (input) CHARACTER*(*)
;;*          The name of the calling subroutine, in either upper case or
;;*          lower case.
;;*
;;*  OPTS    (input) CHARACTER*(*)
;;*          The character options to the subroutine NAME, concatenated
;;*          into a single character string.  For example, UPLO = 'U',
;;*          TRANS = 'T', and DIAG = 'N' for a triangular routine would
;;*          be specified as OPTS = 'UTN'.
;;*
;;*  N1      (input) INTEGER
;;*  N2      (input) INTEGER
;;*  N3      (input) INTEGER
;;*  N4      (input) INTEGER
;;*          Problem dimensions for the subroutine NAME; these may not all
;;*          be required.
;;*
;;* (ILAENV) (output) INTEGER
;;*          >= 0: the value of the parameter specified by ISPEC
;;*          < 0:  if ILAENV = -k, the k-th argument had an illegal value.
;;*
;;*  Further Details
;;*  ===============
;;*
;;*  The following conventions have been used when calling ILAENV from the
;;*  LAPACK routines:
;;*  1)  OPTS is a concatenation of all of the character options to
;;*      subroutine NAME, in the same order that they appear in the
;;*      argument list for NAME, even if they are not used in determining
;;*      the value of the parameter specified by ISPEC.
;;*  2)  The problem dimensions N1, N2, N3, N4 are specified in the order
;;*      that they appear in the argument list for NAME.  N1 is used
;;*      first, N2 second, and so on, and unused problem dimensions are
;;*      passed a value of -1.
;;*  3)  The parameter value returned by ILAENV is checked for validity in
;;*      the calling subroutine.  For example, ILAENV is used to retrieve
;;*      the optimal blocksize for STRTRI as follows:
;;*
;;*      NB = ILAENV( 1, 'STRTRI', UPLO // DIAG, N, -1, -1, -1 )
;;*      IF( NB.LE.1 ) NB = MAX( 1, N )
;;*
;;*  =====================================================================
;;*
;;*     .. Local Scalars ..
;;*  =====================================================================

;;(de ilaenv (ispec  name  opts  n1  n2  n3  n4  )
;;	((-idx0- (-int-)) ispec )
;;	not recognized type
;;	not recognized type
;;	((-idx0- (-int-)) n1 )
;;	((-idx0- (-int-)) n2 )
;;	((-idx0- (-int-)) n3 )
;;	((-idx0- (-int-)) n4 )
;;	(let ((rval 0))
;;	#{ $rval=ilaenv_(IDX_PTR($ispec,int), not recognized type, not recognized type, IDX_PTR($n1,int), IDX_PTR($n2,int), IDX_PTR($n3,int), IDX_PTR($n4,int)) #} rval))

;;interface generated from LAPACK Fortran files automatically
;;Fu Jie Huang, 2002

#? (izmax1 <n>  <cx>  <incx>  )
;;.VP
;;*  Purpose
;;*  =======
;;*
;;*  IZMAX1 finds the index of the element whose real part has maximum
;;*  absolute value.
;;*
;;*  Based on IZAMAX from Level 1 BLAS.
;;*  The change is to use the 'genuine' absolute value.
;;*
;;*  Contributed by Nick Higham for use with ZLACON.
;;*
;;*  Arguments
;;*  =========
;;*
;;*  N       (input) INTEGER
;;*          The number of elements in the vector CX.
;;*
;;*  CX      (input) COMPLEX*16 array, dimension (N)
;;*          The vector whose elements will be summed.
;;*
;;*  INCX    (input) INTEGER
;;*          The spacing between successive values of CX.  INCX >= 1.
;;*
;;* =====================================================================
;;*
;;*     .. Local Scalars ..
;;*  =====================================================================

(de izmax1 (n  cx  incx  )
	((-idx0- (-int-)) n )
	((-idx2- (-double-)) cx )
	((-idx0- (-int-)) incx )
	(let ((rval 0))
	#{ $rval=izmax1_(IDX_PTR($n,int), IDX_PTR($cx,double), IDX_PTR($incx,int)) #} rval))


;;interface generated from LAPACK Fortran files automatically
;;Fu Jie Huang, 2002

#? (lsame <ca>  <cb>  )
;;.VP
;;*  Purpose
;;*  =======
;;*
;;*  LSAME returns .TRUE. if CA is the same letter as CB regardless of
;;*  case.
;;*
;;*  Arguments
;;*  =========
;;*
;;*  CA      (input) CHARACTER*1
;;*  CB      (input) CHARACTER*1
;;*          CA and CB specify the single characters to be compared.
;;*
;;* =====================================================================
;;*
;;*     .. Intrinsic Functions ..
;;*  =====================================================================

(de lsame (ca  cb  )
	((-str-) ca )
	((-str-) cb )
	(let ((rval 0))
	#{ $rval=lsame_($ca->data, $cb->data) #} rval))

;;interface generated from LAPACK Fortran files automatically
;;Fu Jie Huang, 2002

#? (lsamen <n>  <ca>  <cb>  )
;;.VP
;;*  Purpose
;;*  =======
;;*
;;*  LSAMEN  tests if the first N letters of CA are the same as the
;;*  first N letters of CB, regardless of case.
;;*  LSAMEN returns .TRUE. if CA and CB are equivalent except for case
;;*  and .FALSE. otherwise.  LSAMEN also returns .FALSE. if LEN( CA )
;;*  or LEN( CB ) is less than N.
;;*
;;*  Arguments
;;*  =========
;;*
;;*  N       (input) INTEGER
;;*          The number of characters in CA and CB to be compared.
;;*
;;*  CA      (input) CHARACTER*(*)
;;*  CB      (input) CHARACTER*(*)
;;*          CA and CB specify two character strings of length at least N.
;;*          Only the first N characters of each string will be accessed.
;;*
;;* =====================================================================
;;*
;;*     .. Local Scalars ..
;;*  =====================================================================

;;(de lsamen (n  ca  cb  )
;;	((-idx0- (-int-)) n )
;;	not recognized type
;;	not recognized type
;;	(let ((rval 0))
;;	#{ $rval=lsamen_(IDX_PTR($n,int), not recognized type, not recognized type) #} rval))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defvar lapack-x-funclist-nonintel ())

(defvar lapack-x-funclist
  '("icmax1" "ieeeck" "izmax1" "lsame" 
    ;; "ilaenv" "lsamen"
    ))

(let ((dhc-make-lushflags (concat dhc-make-lushflags lapack-cflags)))
  (dhc-make-all 
   ()
   (all ((x (cons "lapack-x-dummy" lapack-x-funclist)))
     (named (downcase x)))
   (append lapack-liblapack lapack-libfortran)))
