/* [+MEQ MatlabEQuilibrium Toolbox+] Swiss Plasma Center EPFL Lausanne 2022. All rights reserved. */
/*
 * The MATMKL library provides C wrappers for BLAS/LAPACK FORTRAN
 * functions provided by MATLAB (mwblas/mwlapack).
 * These C wrappers are equivalent to the ones found in Intel's MKL 
 * or CBLAS/LAPACKE. For simplicity only column-major layout (as
 * used in MATLAB/Simulink) is provided. Only wrappers for the 
 * functions used in libmeq are provided.
 *
 * Note: In mwblas/mwlapack, array dimensions are equivalent to type
 * ptrdiff_t (int64), so conversion from int is performed within
 * these wrappers.
 *
 */

#include "blas.h"

typedef enum {
              CblasColMajor=102    /* column-major arrays */
             } CBLAS_LAYOUT;
/* Do not define CblasRowMajor as this is not supported for matmkl */

typedef enum {
              CblasNoTrans=111,    /* trans='N' */
              CblasTrans=112,      /* trans='T' */
              CblasConjTrans=113   /* trans='C' */
             } CBLAS_TRANSPOSE;

typedef enum {
              CblasUpper=121,      /* uplo ='U' */
              CblasLower=122       /* uplo ='L' */
             } CBLAS_UPLO;


void cblas_scopy(const int n, const float  *x, const int incx, float  *y, const int incy);
void cblas_dcopy(const int n, const double *x, const int incx, double *y, const int incy);

float  cblas_sdot(const int n, const float  *x, const int incx, const float  *y, const int incy);
double cblas_ddot(const int n, const double *x, const int incx, const double *y, const int incy);

void cblas_saxpy(const int n, const float  a, const float  *x, const int incx, float  *y, const int incy);
void cblas_daxpy(const int n, const double a, const double *x, const int incx, double *y, const int incy);

void cblas_sgemm(const CBLAS_LAYOUT Layout, const CBLAS_TRANSPOSE transa, const CBLAS_TRANSPOSE transb,
                 const int m, const int n, const int k, const float  alpha, const float  *a, const int lda,
                 const float  *b, const int ldb, const float  beta, float  *c, const int ldc);
void cblas_dgemm(const CBLAS_LAYOUT Layout, const CBLAS_TRANSPOSE transa, const CBLAS_TRANSPOSE transb,
                 const int m, const int n, const int k, const double alpha, const double *a, const int lda,
                 const double *b, const int ldb, const double beta, double *c, const int ldc);

void cblas_sgemv(const CBLAS_LAYOUT Layout, const CBLAS_TRANSPOSE trans,
                 const int m, const int n, const float  alpha, const float  *a, const int lda,
                 const float  *x, const int incx, const float  beta, float  *y, const int incy);
void cblas_dgemv(const CBLAS_LAYOUT Layout, const CBLAS_TRANSPOSE trans,
                 const int m, const int n, const double alpha, const double *a, const int lda,
                 const double *x, const int incx, const double beta, double *y, const int incy);

void cblas_sspmv(const CBLAS_LAYOUT Layout, const CBLAS_UPLO uplo,
                 const int n, const float  alpha, const float  *ap,
                 const float  *x, const int incx, const float  beta, float  *y, const int incy);
void cblas_dspmv(const CBLAS_LAYOUT Layout, const CBLAS_UPLO uplo,
                 const int n, const double alpha, const double *ap,
                 const double *x, const int incx, const double beta, double *y, const int incy);

void cblas_ssyrk(const CBLAS_LAYOUT Layout, const CBLAS_UPLO uplo, const CBLAS_TRANSPOSE trans,
                 const int n, const int k, const float  alpha, const float  *a, const int lda,
                 const float  beta, float  *c, const int ldc);
void cblas_dsyrk(const CBLAS_LAYOUT Layout, const CBLAS_UPLO uplo, const CBLAS_TRANSPOSE trans,
                 const int n, const int k, const double alpha, const double *a, const int lda,
                 const double beta, double *c, const int ldc);

#include "lapack.h"
#define LAPACK_COL_MAJOR 102

#ifndef lapack_int
#define lapack_int              int
#endif

lapack_int LAPACKE_spptrf(int matrix_layout, char uplo, lapack_int n, float  *ap);
lapack_int LAPACKE_dpptrf(int matrix_layout, char uplo, lapack_int n, double *ap);

lapack_int LAPACKE_spptrs(int matrix_layout, char uplo, lapack_int n, lapack_int nrhs, const float  *ap,
                          float  *b, lapack_int ldb);
lapack_int LAPACKE_dpptrs(int matrix_layout, char uplo, lapack_int n, lapack_int nrhs, const double *ap,
                          double *b, lapack_int ldb);

lapack_int LAPACKE_ssysv(int matrix_layout, char uplo, lapack_int n, lapack_int nrhs, float  *a,
                         lapack_int lda, lapack_int * ipiv, float  *b, lapack_int ldb);
lapack_int LAPACKE_dsysv(int matrix_layout, char uplo, lapack_int n, lapack_int nrhs, double *a,
                         lapack_int lda, lapack_int * ipiv, double *b, lapack_int ldb);

