logo资料库

信号处理库(SigPack + Armadillo + OpenBLAS + FFTW)编译及使用说明.pdf

第1页 / 共13页
第2页 / 共13页
第3页 / 共13页
第4页 / 共13页
第5页 / 共13页
第6页 / 共13页
第7页 / 共13页
第8页 / 共13页
资料共13页,剩余部分请下载后查看
一、OpenBLAS安装和使用
二、Armadillo安装和使用
三、FFTW安装和使用
四、SigPack安装和使用
SigPack 使用说明(MSYS2 Qt5 64-bit) 最后更新:2017.11.16 by L.Song 注:SigPack 基于 Armadillo,需要依赖 Armadillo、OpenBLAS 和 FFTW 支持。 一、OpenBLAS 安装和使用 安装说明: 运行【开始菜单】【MSYS2 64bit】“MSYS2 MSYS”快捷方式。 输入(这里安装的是 64-bit) pacman -S --needed mingw-w64-x86_64-openblas 然后回车,完成安装。 使用示例: 在项目“.pro”文件中,添加 # 引用库 OpenBLAS LIBS += -llibopenblas LIBS += -llibpthread LIBS += -llibgfortran 下面是关于调用 CBLAS 接口的示例,注意头文件的使用。 程序代码如下: #include #include #include "OpenBLAS/cblas.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); int i=0; double A[6] = {1.0,2.0,1.0,-3.0,4.0,-1.0}; double B[6] = {1.0,2.0,1.0,-3.0,4.0,-1.0}; double C[9] = {.5,.5,.5,.5,.5,.5,.5,.5,.5}; 1
cblas_dgemm(CblasColMajor, CblasNoTrans, CblasTrans,3,3,2,1,A, 3, B, 3,2,C,3); for(i=0; i<9; i++) { qDebug() << C[i]; } qDebug() << endl; return a.exec(); } 程序输出结果:11 -9 5 -9 21 -1 5 -1 3 二、Armadillo 安装和使用 方式(1):推荐这种做法 安装说明: 运行【开始菜单】【MSYS2 64bit】“MSYS2 MSYS”快捷方式。 输入(这里安装的是 64-bit) pacman -S --needed mingw-w64-x86_64-armadillo 然后回车,完成安装。 【★ 提醒修改】说明: 在 Armadillo 的头文件“config.hpp”中, 一定要注释掉 #define ARMA_USE_WRAPPER 即最终效果 //#define ARMA_USE_WRAPPER 否则,无法连接使用 OpenBLAS 库。 在项目“.pro”文件中,添加 # 引用库 Armadillo + OpenBLAS #LIBS += -llibarmadillo LIBS += -llibopenblas LIBS += -llibpthread 2
LIBS += -llibgfortran 或者(目前看都可以,先用着上面的吧) # 引用库 Armadillo + OpenBLAS LIBS += -llibarmadillo LIBS += -llibopenblas LIBS += -llibpthread LIBS += -llibgfortran 方式(2):这里没有注释掉 #define ARMA_USE_WRAPPER (不知为何,如果按照这种方式,例如产生随机数矩阵会有错误,全是 0) (因此,不推荐这种方式) 安装说明: 运行【开始菜单】【MSYS2 64bit】“MSYS2 MSYS”快捷方式。 输入(这里安装的是 64-bit) pacman -S --needed mingw-w64-x86_64-hdf5 pacman -S --needed mingw-w64-x86_64-armadillo 然后回车,完成安装。 说明:HDF5 是用于存储和分发科学数据的一种自我描述、多对象文件格式, 在 Armadillo 的头文件“config.hpp”中有用到。 【★ Armadillo 安装后需要修改】修改说明: 在 Armadillo 的头文件“config.hpp”中,一共有六处, 需要将文件夹 C:/building/msys64/mingw64/ 修改为 D:/ProgramOther/msys64/mingw64/ 这才是正确的 MSYS2 MinGW-w64 64-bit 实际安装目录。否则编译报错。 在项目“.pro”文件中,添加 # 引用库 Armadillo + OpenBLAS LIBS += -llibarmadillo 3
LIBS += -llibhdf5 LIBS += -llibopenblas LIBS += -llibpthread LIBS += -llibgfortran 使用示例:(Armadillo + 依赖 OpenBLAS) 方式(1)、方式(2)采用同一个示例,注意头文件的使用。代码如下: #include #include #include using namespace std; using namespace arma; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // Initialize the random generator arma_rng::set_seed_random(); // Create a 4x4 random matrix and print it on the screen Mat A = randu(4,4); cout << "A:\n" << A << "\n"; // Multiply A with his transpose: cout << "A * A.t() =\n"; cout << A * A.t() << "\n"; // Access/Modify rows and columns from the array: A.row(0) = A.row(1) + A.row(3); A.col(3).zeros(); cout << "add rows 1 and 3, store result in row 0, also fill 4th column with zeros:\n"; cout << "A:\n" << A << "\n"; // Create a new diagonal matrix using the main diagonal of A: MatB = diagmat(A); cout << "B:\n" << B << "\n"; // Save matrices A and B: 4
A.save("A_mat.txt", arma_ascii); B.save("B_mat.txt", arma_ascii); return a.exec(); } 三、FFTW 安装和使用 安装说明: 运行【开始菜单】【MSYS2 64bit】“MSYS2 MSYS”快捷方式。 输入(这里安装的是 64-bit) pacman -S --needed mingw-w64-x86_64-fftw 然后回车,完成安装。 使用示例: 在项目“.pro”文件中,添加 # 引用库 FFTW LIBS += -llibfftw3 LIBS += -llibfftw3f LIBS += -llibfftw3l 注意头文件的使用。程序代码如下: #include #include // 文件操作 #include // 输出调试信息 #include // 常用数学函数库 #include // 高精度(us 级)计时 #include "fftw3.h" using namespace std; #define PI 3.1415926535897932 // 圆周率 int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); 5
// 运行计时(高精度,微秒级 us) LARGE_INTEGER litmp; QueryPerformanceFrequency(&litmp); // 取得高精度运行计数器的频率 f,单位 是每秒多少次 double dfFreq = (double)litmp.QuadPart; QueryPerformanceCounter(&litmp); // 取得高精度运行计数器的数值 LONGLONG qpartBegin = litmp.QuadPart; // 记录当前时钟 ---- 总的开始 int nlen = 8192; // 数据点数 double * input = (double *)fftw_malloc(sizeof(double) * nlen); fftw_complex * output = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * nlen); qreal * mag = new qreal[nlen]; // 幅值 qreal * pha = new qreal[nlen]; // 相位 // FFT 创建变换方案(fftw_plan) fftw_plan p = fftw_plan_dft_r2c_1d(nlen, input, output, FFTW_MEASURE); // FFT 执行变换 ---- 第一次执行,耗时较长,自动选最优方案(对应上面 FFTW_MEASURE) fftw_execute(p); QueryPerformanceCounter(&litmp); // 取得高精度运行计数器的数值 LONGLONG qpartInit = litmp.QuadPart; // 记录当前时钟 ---- 相当于初始化 完毕 double initMinus = (double)(qpartInit - qpartBegin); // 计算计数器值 double initTime = initMinus / dfFreq; // 获得对应时间,单位为秒 LONGLONG initCost = initTime * 1000000; // 乘以 1000000,精确到微秒级 (us) qDebug() << "The first FFT execute (FFTW_MEASURE) cost: " << initCost << " us (== 0.001 ms)" << endl; // 输入信号 ---- 实数 double dx = 1.0 / nlen; for (int i = 0; i< nlen; i++) { double f = 100; // 频率,Hz double t = i * dx; double x = 2 * PI * f * t; 6
double y = sin(x) + cos(2 * x); input[i] = y; } QueryPerformanceCounter(&litmp); // 取得高精度运行计数器的数值 LONGLONG qpartStart = litmp.QuadPart; // 记录当前时钟 ---- 开始执行 FFT 变换 int nloops = 100; // 循环执行次数 LONGLONG loopCosts[100]; // 记录每次循环所需的时间 for (int loopidx = 0; loopidx < nloops; loopidx++) { QueryPerformanceCounter(&litmp); // 取得高精度运行计数器的数值 LONGLONG qpartFrom = litmp.QuadPart; // 记录当前时钟 // FFT 执行变换 fftw_execute(p); QueryPerformanceCounter(&litmp); // 取得高精度运行计数器的数值 LONGLONG qpartTo = litmp.QuadPart; // 记录当前时钟 double tempMinus = (double)(qpartTo - qpartFrom); // 计算计数器值 double tempTime = tempMinus / dfFreq; // 获得对应时间,单位为秒 loopCosts[loopidx] = tempTime * 1000000; // 乘以 1000000,精确到微 秒级(us) } // end for QueryPerformanceCounter(&litmp); // 取得高精度运行计数器的数值 LONGLONG qpartEnd = litmp.QuadPart; // 记录当前时钟 ---- 完毕,FFT 变换 已执行 double dfMinus = (double)(qpartEnd - qpartStart); // 计算计数器值 double dfTime = dfMinus / dfFreq; // 获得对应时间,单位为秒 LONGLONG Usingtime = dfTime * 1000000; // 乘以 1000000,精确到微秒级 (us) // 将运行计时结果保存文件 QFile fileTimecost("timecost.txt"); if (!fileTimecost.open(QIODevice::WriteOnly | QIODevice::Text)) { qDebug() << "Can't save timecost file!" << endl; } 7
else { QTextStream stream(&fileTimecost); stream <<"Time unit: us == 0.001 ms" << endl; stream << endl; stream << nloops << " loops of " << nlen << " point FFT, total time cost: " << Usingtime << endl; stream << endl; for (int i = 0; i < nloops; i++) { LONGLONG temp = loopCosts[i]; stream << "Loop " << i+1 << " : "; stream << temp << endl; } stream.flush(); fileTimecost.close(); } // 将幅值、相位的计算结果保存文件,其实也就是最后一次循环的计算结果 for (int j = 0; j < nlen; j++) { double real = output[j][0]; //Extract real component double imag = output[j][1]; //Extract imaginary component mag[j] = qSqrt((real*real) + (imag*imag)); // Calculate the Magnitude pha[j] = qAtan2(imag, real); // Calculate the Phase } QFile fileMag("mag.txt"); if (!fileMag.open(QIODevice::WriteOnly | QIODevice::Text)) { qDebug() << "Can't save mag file!" << endl; } else { QTextStream stream(&fileMag); for (int j = 0; j < nlen; j++) { double temp = mag[j]; stream << temp << endl; } stream.flush(); 8
分享到:
收藏