// 下列 ifdef 块是创建使从 DLL 导出更简单的
// 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 EIGENSOLVER_EXPORTS
// 符号编译的。在使用此 DLL 的
// 任何项目上不应定义此符号。这样，源文件中包含此文件的任何其他项目都会将
// EIGENSOLVER_API 函数视为是从 DLL 导入的，而此 DLL 则将用此宏定义的
// 符号视为是被导出的。
#ifdef EIGENSOLVER_STATIC
#define EIGENSOLVER_API
#elif defined(EIGENSOLVER_EXPORTS)
#define EIGENSOLVER_API __declspec(dllexport)
#else
#define EIGENSOLVER_API __declspec(dllimport)
#endif

#include <string.h>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <stdlib.h>
#include <complex>
#include <memory>
#include <algorithm>

EIGENSOLVER_API int fneigensolver(void);

//      A_Roffsets  A_Cindices  A_complex    矩阵A
//      B_Roffsets  B_Cindices  B_complex    矩阵B
//      A_n         B_n                      矩阵维数
//      A_nzero     B_nzero                  非零元
//      target_real target_imag              目标值
//      option                               搜索方式
//      nums                                 要求数量
//      eigenValues                          存放特征值数组
//      eigenVectors                         存放特征向量数组
EIGENSOLVER_API void complexEigenSolver(int *A_Roffsets,
    int *A_Cindices,
    std::complex<double> *A_complex,
    int *B_Roffsets,
    int *B_Cindices,
    std::complex<double> *B_complex,
    int A_n,
    int B_n,
    int A_nzero,
    int B_nzero,
    double target_real,
    double target_imag,
    int option,
    int nums,
    std::complex<double> *eigenValues,
    std::complex<double> **eigenVectors);


//      A_Roffsets  A_Cindices  A_real      矩阵A
//      B_Roffsets  B_Cindices  B_real      矩阵B
//      A_n         B_n                     矩阵维数
//      A_nzero     B_nzero                 非零元
//      target                              目标值
//      option                              搜索方式
//      0-最接近目标值的特征值(幅度)-1-实部最接近目标的特征值 nums 要求数量
//      eigenValues                         存放特征值数组
//      eigenVectors                        存放特征向量数组
EIGENSOLVER_API void realEigenSolver(int *A_Roffsets,
    int *A_Cindices,
    double *A_real,
    int *B_Roffsets,
    int *B_Cindices,
    double *B_real,
    int A_n,
    int B_n,
    int A_nzero,
    int B_nzero,
    double target,
    int option,
    int nums,
    double *eigenValues,
    double **eigenVectors);