function-test.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. // test_complex_fft.c
  2. #include "kiss_fft.h"
  3. #include "kiss_fftr.h"
  4. #include "kiss_fftnd.h"
  5. #include "kiss_fftndr.h"
  6. // #include "kiss_fastfir.h"
  7. #include <stdio.h>
  8. int test_complex(); //{ printf("\n[1] 复数FFT\n"); /* 代码同示例1 */ }
  9. int test_real(); //{ printf("\n[2] 实数FFT\n"); /* 代码同示例2 */ }
  10. int test_2d(); //{ printf("\n[3] 2D FFT\n"); /* 代码同示例3 */ }
  11. int test_2d_real(); //{ printf("\n[4] 2D实数FFT\n"); /* 代码同示例4 */ }
  12. int test_conv(); //{ printf("\n[5] 快速卷积\n"); /* 代码同示例5 */ }
  13. int main() {
  14. printf("=== KissFFT 功能测试集 ===\n");
  15. test_complex();
  16. test_real();
  17. test_2d();
  18. test_2d_real();
  19. // test_conv();
  20. printf("\n所有测试完成!\n");
  21. return 0;
  22. }
  23. // int test_conv() {
  24. // int N = 8;
  25. // // 创建低通滤波器(系数)
  26. // float coeffs[8] = {0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125}; // 均值滤波
  27. // // 初始化快速FIR
  28. // kiss_fastfir_cfg cfg = kiss_fastfir_alloc(coeffs, 8, NULL, NULL);
  29. // // 输入信号
  30. // float in[8] = {1, 2, 3, 4, 5, 6, 7, 8};
  31. // // 输出信号
  32. // float out[8];
  33. // // 执行快速卷积
  34. // kiss_fastfir(cfg, in, out, 8);
  35. // printf("=== 快速卷积测试 ===\n");
  36. // printf("输入信号: ");
  37. // for (int i = 0; i < 8; i++) printf("%.1f ", in[i]);
  38. // printf("\n滤波器: ");
  39. // for (int i = 0; i < 8; i++) printf("%.3f ", coeffs[i]);
  40. // printf("\n输出信号: ");
  41. // for (int i = 0; i < 8; i++) printf("%.3f ", out[i]);
  42. // printf("\n\n说明:输出是输入与滤波器的卷积结果\n");
  43. // kiss_fastfir_free(cfg);
  44. // return 0;
  45. // }
  46. int test_2d_real() {
  47. int dims[2] = {4, 4};
  48. // 2D实数FFT配置
  49. kiss_fftndr_cfg cfg_forward = kiss_fftndr_alloc(dims, 2, 0, NULL, NULL);
  50. kiss_fftndr_cfg cfg_inverse = kiss_fftndr_alloc(dims, 2, 1, NULL, NULL);
  51. // 2D实数输入
  52. float in_real[16];
  53. for (int i = 0; i < 16; i++) {
  54. in_real[i] = (i % 4 == 0) ? 1.0 : 0.0; // 第0列为1
  55. }
  56. // 输出(复数,压缩格式)
  57. kiss_fft_cpx out_freq[16];
  58. // IFFT输出
  59. float out_real[16];
  60. // 正向变换
  61. kiss_fftndr(cfg_forward, in_real, out_freq);
  62. // 逆向变换
  63. kiss_fftndri(cfg_inverse, out_freq, out_real);
  64. printf("=== 2D实数FFT测试 ===\n");
  65. printf("输入(实数):\n");
  66. for (int i = 0; i < 4; i++) {
  67. for (int j = 0; j < 4; j++) {
  68. printf("%.1f ", in_real[i*4+j]);
  69. }
  70. printf("\n");
  71. }
  72. printf("\n重建(实数):\n");
  73. for (int i = 0; i < 4; i++) {
  74. for (int j = 0; j < 4; j++) {
  75. printf("%.1f ", out_real[i*4+j]);
  76. }
  77. printf("\n");
  78. }
  79. free(cfg_forward);
  80. free(cfg_inverse);
  81. return 0;
  82. }
  83. int test_2d() {
  84. int dims[2] = {4, 4}; // 4x4矩阵
  85. // 分配配置
  86. kiss_fftnd_cfg cfg_forward = kiss_fftnd_alloc(dims, 2, 0, NULL, NULL);
  87. kiss_fftnd_cfg cfg_inverse = kiss_fftnd_alloc(dims, 2, 1, NULL, NULL);
  88. // 2D输入数据(4x4 = 16个点)
  89. kiss_fft_cpx in[16];
  90. for (int i = 0; i < 16; i++) {
  91. in[i].r = (i % 4 == 0) ? 1.0 : 0.0; // 第0列为1,其他为0
  92. in[i].i = 0;
  93. }
  94. kiss_fft_cpx out[16];
  95. kiss_fft_cpx reconstructed[16];
  96. // 2D FFT
  97. kiss_fftnd(cfg_forward, in, out);
  98. // 2D IFFT
  99. kiss_fftnd(cfg_inverse, out, reconstructed);
  100. printf("=== 2D FFT测试 (4x4) ===\n");
  101. printf("输入矩阵(只第0列为1):\n");
  102. for (int i = 0; i < 4; i++) {
  103. for (int j = 0; j < 4; j++) {
  104. printf("%.1f\t", in[i*4+j].r);
  105. }
  106. printf("\n");
  107. }
  108. printf("\n2D FFT频谱(幅度):\n");
  109. for (int i = 0; i < 4; i++) {
  110. for (int j = 0; j < 4; j++) {
  111. float mag = sqrt(out[i*4+j].r * out[i*4+j].r + out[i*4+j].i * out[i*4+j].i);
  112. printf("%.2f\t", mag);
  113. }
  114. printf("\n");
  115. }
  116. printf("\n重建矩阵:\n");
  117. for (int i = 0; i < 4; i++) {
  118. for (int j = 0; j < 4; j++) {
  119. printf("%.1f\t", reconstructed[i*4+j].r);
  120. }
  121. printf("\n");
  122. }
  123. free(cfg_forward);
  124. free(cfg_inverse);
  125. return 0;
  126. }
  127. int test_real() {
  128. int N = 8;
  129. // 实数FFT配置
  130. kiss_fftr_cfg cfg_forward = kiss_fftr_alloc(N, 0, NULL, NULL);
  131. kiss_fftr_cfg cfg_inverse = kiss_fftr_alloc(N, 1, NULL, NULL);
  132. // 实数输入信号
  133. float in_real[N];
  134. for (int i = 0; i < N; i++) {
  135. in_real[i] = cos(2 * M_PI * i / N) + 0.5 * sin(4 * M_PI * i / N);
  136. }
  137. // FFT输出(复数,N/2+1个点)
  138. kiss_fft_cpx out_freq[N/2+1];
  139. // IFFT输出(实数)
  140. float out_real[N];
  141. // 正向实数FFT
  142. kiss_fftr(cfg_forward, in_real, out_freq);
  143. // 逆向实数FFT
  144. kiss_fftri(cfg_inverse, out_freq, out_real);
  145. printf("=== 实数FFT测试 (N=%d) ===\n", N);
  146. printf("原始实数信号 -> FFT -> IFFT\n\n");
  147. printf("索引\t原始\t\t频谱(复数)\t\t重建\n");
  148. for (int i = 0; i < N; i++) {
  149. if (i <= N/2) {
  150. printf("%d\t%.3f\t\t%.3f%+.3fj\t%.3f\n",
  151. i, in_real[i], out_freq[i].r, out_freq[i].i, out_real[i]);
  152. } else {
  153. printf("%d\t%.3f\t\t-\t\t%.3f\n", i, in_real[i], out_real[i]);
  154. }
  155. }
  156. // 验证
  157. float error = 0;
  158. for (int i = 0; i < N; i++) {
  159. error += fabs(in_real[i] - out_real[i]);
  160. }
  161. printf("\n重建误差: %f\n", error / N);
  162. kiss_fftr_free(cfg_forward);
  163. kiss_fftr_free(cfg_inverse);
  164. return 0;
  165. }
  166. int test_complex() {
  167. int N = 8;
  168. // 分配配置
  169. kiss_fft_cfg cfg_forward = kiss_fft_alloc(N, 0, NULL, NULL);
  170. kiss_fft_cfg cfg_inverse = kiss_fft_alloc(N, 1, NULL, NULL);
  171. // 输入信号:复数指数 e^(j*2π*k/N)
  172. kiss_fft_cpx in[N];
  173. for (int i = 0; i < N; i++) {
  174. in[i].r = cos(2 * M_PI * i / N); // 实部
  175. in[i].i = sin(2 * M_PI * i / N); // 虚部
  176. }
  177. // 输出缓冲区
  178. kiss_fft_cpx out[N];
  179. kiss_fft_cpx reconstructed[N];
  180. // 正向FFT
  181. kiss_fft(cfg_forward, in, out);
  182. // 逆向FFT
  183. kiss_fft(cfg_inverse, out, reconstructed);
  184. // 打印结果
  185. printf("=== 复数FFT测试 (N=%d) ===\n", N);
  186. printf("原始信号 -> FFT -> IFFT\n\n");
  187. printf("原始\t\t\tFFT输出\t\t\t重建信号\n");
  188. for (int i = 0; i < N; i++) {
  189. printf("%.2f%+.2fj\t%.2f%+.2fj\t%.2f%+.2fj\n",
  190. in[i].r, in[i].i,
  191. out[i].r, out[i].i,
  192. reconstructed[i].r, reconstructed[i].i);
  193. }
  194. // 验证精度
  195. float error = 0;
  196. for (int i = 0; i < N; i++) {
  197. error += fabs(in[i].r - reconstructed[i].r) + fabs(in[i].i - reconstructed[i].i);
  198. }
  199. printf("\n重建误差: %f\n", error / N);
  200. free(cfg_forward);
  201. free(cfg_inverse);
  202. return 0;
  203. }