/**
 * @brief Wrapper over FEAST FORTRAN library.
 *
 * @author Yunhai Li (liyunhai1016@hotmail.com)
 *
 * @copyright Copyright (c) 2024, TBPLaS develop team.
 *
 * @note
 * 1. FEAST provides C interface instead of C++. A wrapper is required
 *    to avoid compiling and linking errors.
 * 2. FORTRAN array index begins from 1. Increase indtpr and indices from C++
 *    by 1 before calling functions defined here.
 */
#ifdef WITH_FEAST
#ifndef TBPLAS_DIAG_FEAST_WRAPPER_H
#define TBPLAS_DIAG_FEAST_WRAPPER_H

// Must be treated as C to avoid name mangling
extern "C" {

typedef struct _FeastDenseArgs {
    int num_orb; // N, LDA and LDB
    double* hk; // matrix A
    double* sk; // matrix B
    int* fpm;
    double eps_out;
    double e_min;
    double e_max;
    int subspace_size; // M0
    int num_states; // M, mode
    double* eig_val; // lambda
    double* eig_vec; // q
    double* residual;
} FeastDenseArgs;

typedef struct _FeastCsrArgs {
    int num_orb; // N
    double* values_h; // sa
    int* indptr_h; // isa
    int* indices_h; // jsa
    double* values_s; // sb
    int* indptr_s; // isb
    int* indices_s; // jsb
    int* fpm;
    double eps_out;
    double e_min;
    double e_max;
    int subspace_size; // M0
    int num_states; // M, mode
    double* eig_val; // lambda
    double* eig_vec; // q
    double* residual;
} FeastCsrArgs;

void feast_init_wrapper(int* fpm);

void zfeast_heev_wrapper(FeastDenseArgs* args);

void zfeast_hegv_wrapper(FeastDenseArgs* args);

void zfeast_hcsrev_wrapper(FeastCsrArgs* args);

void zfeast_hcsrgv_wrapper(FeastCsrArgs* args);

} // extern "C"
#endif // TBPLAS_DIAG_FEAST_WRAPPER_H
#endif // WITH_FEAST