/*
 * Copyright (C) 1996-2011 Daniel Waggoner
 *
 * This 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.
 *
 * It 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.
 *
 * If you did not received a copy of the GNU General Public License
 * with this software, see <http://www.gnu.org/licenses/>.
 */

#ifndef __BLAS_LAPACK__
#define __BLAS_LAPACK__

#if !defined(MATLAB_MEX_FILE) && !defined(OCTAVE_MEX_FILE)

#include "dw_std.h"

#ifdef __cplusplus
extern "C"
{
#endif

/**************** Linux defines because underscore is appended *****************/
#ifdef __linux__

/* BLAS */
#define dscal     dscal_     // Blas scalar times vector
#define sscal     sscal_

#define daxpy     daxpy_     // Blas vector plus scalar times vector
#define saxpy     saxpy_

#define dgemm     dgemm_     // Blas matrix multiplication
#define sgemm     sgemm_

#define dtrsm     dtrsm_     // Solves triangular system
#define strsm     strsm_

#define dtrmm     dtrmm_     // Blas matrix multiplication - triangular
#define strmm     strmm_

#define dgemv     dgemv_     // Blas vector matrix multiplication
#define sgemv     sgemv_


/* LAPACK */ 
#define dgesdd    dgesdd_    // SVD decomposition (divide and conquer)
#define sgesdd    sgesdd_

#define dgesvd    dgesvd_    // SVD decomposition (QR)
#define sgesvd    sgesvd_

#define dgetrf    dgetrf_    // LU decomposition
#define sgetrf    sgetrf_

#define dgetrs    dgetrs_    // Solves system using previously computed LU decomposition
#define sgetrs    sgetrs_

#define dgesv     dgesv_     // Solves system using LU decomposition
#define sgesv     sgesv_

#define dgeqrf    dgeqrf_    // QR decomposition
#define sgetrf    sgetrf_

#define dorgqr    dorgqr_    // Forms orthogonal matrix from Housholder matrices created by dgeqrf
#define sorgqr    sorgqr_

#define dgelqf    dgelqf_    // LQ decompostion
#define sgelqf    sgelqf_

#define dorglq    dorglq_    // Forms orthogonal matrix from Housholder matrices created by dgeqlq
#define sorglq    sorglq_

#define dgges     dgges_     // Generalized Schur decomposition
#define sgges     sgges_

#define dtgsen    dtgsen_    // Reorders generalized Schur decomposition
#define stgsen    stgsen_

#define dtgexc    dtgexc_    // Reorders generalized Schur decomposition
#define stgexc    stgexc_

#define dsyev     dsyev_
#define ssyev     ssyev_

#define dgeev     dgeev_     // Computes eigenvalues and eigenvectors
#define sgeev     sgeev_

#define dsyevr    dsyevr_    // Computes eigenvalues and eigenvectors of a symmetric matrix
#define ssyevr    ssyevr_

#define dpotrf    dpotrf_    // Computes the Cholesky decompostion
#define spotrf    spotrf_

#define dpotri    dpotri_
#define spotri    spotri_

#define dgeev     dgeev_     
#define sgeev     sgeev_
#endif
/*******************************************************************************/



/*******************************************************************************/
/* BLAS */
void dscal(blas_int*,double*,double*,blas_int*);
void sscal(blas_int*,float*,float*,blas_int*);

void daxpy(blas_int*,double*,double*,blas_int*,double*,blas_int*);
void saxpy(blas_int*,float*,float*,blas_int*,float*,blas_int*);

void dgemm(char*,char*,blas_int*,blas_int*,blas_int*,double*,double*,blas_int*,double*,blas_int*,double*,double*,blas_int*);
void sgemm(char*,char*,blas_int*,blas_int*,blas_int*,float*,float*,blas_int*,float*,blas_int*,float*,float*,blas_int*);

void dtrsm(char*,char*,char*,char*,blas_int*,blas_int*,double*,double*,blas_int*,double*,blas_int*);
void strsm(char*,char*,char*,char*,blas_int*,blas_int*,float*,float*,blas_int*,float*,blas_int*);

void dtrmm(char*,char*,char*,char*,blas_int*,blas_int*,double*,double*,blas_int*,double*,blas_int*);
void strmm(char*,char*,char*,char*,blas_int*,blas_int*,float*,float*,blas_int*,float*,blas_int*);

void dgemv(char*,blas_int*,blas_int*,double*,double*,blas_int*,double*,blas_int*,double*,double*,blas_int*);
void sgemv(char*,blas_int*,blas_int*,float*,float*,blas_int*,float*,blas_int*,float*,float*,blas_int*);


/* LAPACK */
void dgesdd(char*,lapack_int*,lapack_int*,double*,lapack_int*,double*,double*,lapack_int*,double*,lapack_int*,double*,lapack_int*,lapack_int*,lapack_int*);
void sgesdd(char*,lapack_int*,lapack_int*,float*,lapack_int*,float*,float*,lapack_int*,float*,lapack_int*,float*,lapack_int*,lapack_int*,lapack_int*);

void dgesvd(char*,char*,lapack_int*,lapack_int*,double*,lapack_int*,double*,double*,lapack_int*,double*,lapack_int*,double*,lapack_int*,lapack_int*);
void sgesvd(char*,char*,lapack_int*,lapack_int*,float*,lapack_int*,float*,float*,lapack_int*,float*,lapack_int*,float*,lapack_int*,lapack_int*);

void dgeqrf(lapack_int*,lapack_int*,double*,lapack_int*,double*,double*,lapack_int*,lapack_int*);
void sgeqrf(lapack_int*,lapack_int*,float*,lapack_int*,float*,float*,lapack_int*,lapack_int*);

void dgetrf(lapack_int*,lapack_int*,double*,lapack_int*,lapack_int*,lapack_int*);
void sgetrf(lapack_int*,lapack_int*,float*,lapack_int*,lapack_int*,lapack_int*);

void dgesv(lapack_int*,lapack_int*,double*,lapack_int*,lapack_int*,double*,lapack_int*,lapack_int*);
void sgesv(lapack_int*,lapack_int*,float*,lapack_int*,lapack_int*,float*,lapack_int*,lapack_int*);

void dgetrs(char*,lapack_int*,lapack_int*,double*,lapack_int*,lapack_int*,double*,lapack_int*,lapack_int*);
void sgetrs(char*,lapack_int*,lapack_int*,float*,lapack_int*,lapack_int*,float*,lapack_int*,lapack_int*);

void dorgqr(lapack_int*,lapack_int*,lapack_int*,double*,lapack_int*,double*,double*,lapack_int*,lapack_int*);
void sorgqr(lapack_int*,lapack_int*,lapack_int*,float*,lapack_int*,float*,float*,lapack_int*,lapack_int*);

void dgelqf(lapack_int*,lapack_int*,double*,lapack_int*,double*,double*,lapack_int*,lapack_int*);
void sgelqf(lapack_int*,lapack_int*,float*,lapack_int*,float*,float*,lapack_int*,lapack_int*);

void dorglq(lapack_int*,lapack_int*,lapack_int*,double*,lapack_int*,double*,double*,lapack_int*,lapack_int*);
void sorglq(lapack_int*,lapack_int*,lapack_int*,float*,lapack_int*,float*,float*,lapack_int*,lapack_int*);

void dgges(char*,char*,char*,lapack_int*,lapack_int*,double*,lapack_int*,double*,lapack_int*,lapack_int*,double*,double*,double*,double*,lapack_int*,double*,lapack_int*,double*,lapack_int*,void*,lapack_int*);
void sgges(char*,char*,char*,lapack_int*,lapack_int*,float*,lapack_int*,float*,lapack_int*,lapack_int*,float*,float*,float*,float*,lapack_int*,float*,lapack_int*,float*,lapack_int*,void*,lapack_int*);

void dtgsen(lapack_int*,lapack_int*,lapack_int*,lapack_int*,lapack_int*,double*,lapack_int*,double*,lapack_int*,double*,double*,double*,double*,lapack_int*,double*,lapack_int*,lapack_int*,double*,double*,double*,double*,lapack_int*,lapack_int*,lapack_int*,lapack_int*);
void stgsen(lapack_int*,lapack_int*,lapack_int*,lapack_int*,lapack_int*,float*,lapack_int*,float*,lapack_int*,float*,float*,float*,float*,lapack_int*,float*,lapack_int*,lapack_int*,float*,float*,float*,float*,lapack_int*,lapack_int*,lapack_int*,lapack_int*);

void dtgexc(lapack_int*,lapack_int*,lapack_int*,double*,lapack_int*,double*,lapack_int*,double*,lapack_int*,double*,lapack_int*,lapack_int*,lapack_int*,double*,lapack_int*,lapack_int*);
void stgexc(lapack_int*,lapack_int*,lapack_int*,float*,lapack_int*,float*,lapack_int*,float*,lapack_int*,float*,lapack_int*,lapack_int*,lapack_int*,float*,lapack_int*,lapack_int*);

void dsyev(char*,char*,lapack_int*,double*,lapack_int*,double*,double*,lapack_int*,lapack_int*);
void ssyev(char*,char*,lapack_int*,float*,lapack_int*,float*,float*,lapack_int*,lapack_int*);

void dsyevr(char*,char*,char*,lapack_int*,double*,lapack_int*,double*,double*,lapack_int*,lapack_int*,double*,lapack_int*,double*,double*,lapack_int*,lapack_int*,double*,lapack_int*,lapack_int*,lapack_int*,lapack_int*);
void ssyevr(char*,char*,char*,lapack_int*,float*,lapack_int*,float*,float*,lapack_int*,lapack_int*,float*,lapack_int*,float*,float*,lapack_int*,lapack_int*,float*,lapack_int*,lapack_int*,lapack_int*,lapack_int*);

void dgeev(char*,char*,lapack_int*,double*,lapack_int*,double*,double*,double*,lapack_int*,double*,lapack_int*,double*,lapack_int*,lapack_int*);
void sgeev(char*,char*,lapack_int*,float*,lapack_int*,float*,float*,float*,lapack_int*,float*,lapack_int*,float*,lapack_int*,lapack_int*);

void dpotrf(char*,lapack_int*,double*,lapack_int*,lapack_int*);
void spotrf(char*,lapack_int*,float*,lapack_int*,lapack_int*);

void dpotri(char*,lapack_int*,double*,lapack_int*,lapack_int*);
void spotri(char*,lapack_int*,float*,lapack_int*,lapack_int*);
/*******************************************************************************/

#ifdef __cplusplus
}
#endif

#endif

#endif
