/dft/naivetest.c

https://github.com/shibatch/SSRC · C · 413 lines · 254 code · 125 blank · 34 comment · 52 complexity · 5456ee850c3aac208bf50578d7e17d10 MD5 · raw file

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdint.h>
  4. #include <assert.h>
  5. #include <math.h>
  6. #include <complex.h>
  7. #include <time.h>
  8. #include "sleefdft.h"
  9. #ifndef M_PI
  10. #define M_PI 3.141592653589793238462643383279502884
  11. #endif
  12. #define THRES 1e-4
  13. #define max(x, y) ((x) > (y) ? (x) : (y))
  14. typedef double complex cmpl;
  15. cmpl omega(double n, double kn) {
  16. return cexp((-2 * M_PI * _Complex_I / n) * kn);
  17. }
  18. void forward(cmpl *ts, cmpl *fs, int len) {
  19. int k, n;
  20. for(k=0;k<len;k++) {
  21. fs[k] = 0;
  22. for(n=0;n<len;n++) {
  23. fs[k] += ts[n] * omega(len, n*k);
  24. }
  25. }
  26. }
  27. void backward(cmpl *fs, cmpl *ts, int len) {
  28. int k, n;
  29. for(k=0;k<len;k++) {
  30. ts[k] = 0;
  31. for(n=0;n<len;n++) {
  32. ts[k] += fs[n] * omega(-len, n*k);
  33. }
  34. }
  35. }
  36. // complex forward
  37. int check_cf(int n) {
  38. int i;
  39. SleefDFT_real *sx = (SleefDFT_real *)SleefDFT_malloc(n*2 * sizeof(SleefDFT_real));
  40. SleefDFT_real *sy = (SleefDFT_real *)SleefDFT_malloc(n*2 * sizeof(SleefDFT_real));
  41. cmpl *ts = (cmpl *)malloc(sizeof(cmpl)*n);
  42. cmpl *fs = (cmpl *)malloc(sizeof(cmpl)*n);
  43. //
  44. for(i=0;i<n;i++) {
  45. ts[i] = (2.0 * (rand() / (double)RAND_MAX) - 1) + (2.0 * (rand() / (double)RAND_MAX) - 1) * _Complex_I;
  46. sx[(i*2+0)] = creal(ts[i]);
  47. sx[(i*2+1)] = cimag(ts[i]);
  48. }
  49. //
  50. forward(ts, fs, n);
  51. struct SleefDFT *p = SleefDFT_init(SLEEF_MODE_DEBUG | SLEEF_MODE_VERBOSE, n);
  52. SleefDFT_execute(p, sy, sx);
  53. //
  54. int success = 1;
  55. double maxError = 0;
  56. for(i=0;i<n;i++) {
  57. if ((fabs(sy[(i*2+0)] - creal(fs[i])) > THRES) ||
  58. (fabs(sy[(i*2+1)] - cimag(fs[i])) > THRES)) {
  59. success = 0;
  60. }
  61. //printf("%g, %g\n", sy[(2*i+0)], creal(fs[i]));
  62. //printf("%g, %g\n", sy[(2*i+1)], cimag(fs[i]));
  63. maxError = max(maxError, fabs((sy[(i*2+0)] - creal(fs[i]))));
  64. maxError = max(maxError, fabs((sy[(i*2+1)] - cimag(fs[i]))));
  65. }
  66. printf("maxError = %g\n", maxError);
  67. //
  68. free(fs);
  69. free(ts);
  70. SleefDFT_free(sx);
  71. SleefDFT_free(sy);
  72. SleefDFT_dispose(p);
  73. //
  74. return success;
  75. }
  76. // complex backward
  77. int check_cb(int n) {
  78. int i;
  79. SleefDFT_real *sx = (SleefDFT_real *)SleefDFT_malloc(sizeof(SleefDFT_real)*n*2);
  80. SleefDFT_real *sy = (SleefDFT_real *)SleefDFT_malloc(sizeof(SleefDFT_real)*n*2);
  81. cmpl *ts = (cmpl *)malloc(sizeof(cmpl)*n);
  82. cmpl *fs = (cmpl *)malloc(sizeof(cmpl)*n);
  83. //
  84. for(i=0;i<n;i++) {
  85. fs[i] = (2.0 * (rand() / (double)RAND_MAX) - 1) + (2.0 * (rand() / (double)RAND_MAX) - 1) * _Complex_I;
  86. sx[(i*2+0)] = creal(fs[i]);
  87. sx[(i*2+1)] = cimag(fs[i]);
  88. }
  89. backward(fs, ts, n);
  90. struct SleefDFT *p = SleefDFT_init(SLEEF_MODE_DEBUG | SLEEF_MODE_BACKWARD, n);
  91. SleefDFT_execute(p, sy, sx);
  92. //
  93. int success = 1;
  94. for(i=0;i<n;i++) {
  95. if ((fabs(sy[(i*2+0)] - creal(ts[i])) > THRES) ||
  96. (fabs(sy[(i*2+1)] - cimag(ts[i])) > THRES)) {
  97. success = 0;
  98. }
  99. }
  100. //
  101. free(fs);
  102. free(ts);
  103. SleefDFT_free(sx);
  104. SleefDFT_free(sy);
  105. SleefDFT_dispose(p);
  106. //
  107. return success;
  108. }
  109. int check_rf(int n) {
  110. int i;
  111. SleefDFT_real *sx = (SleefDFT_real *)SleefDFT_malloc(n * sizeof(SleefDFT_real));
  112. SleefDFT_real *sy = (SleefDFT_real *)SleefDFT_malloc(n * sizeof(SleefDFT_real));
  113. cmpl *ts = (cmpl *)malloc(sizeof(cmpl)*n);
  114. cmpl *fs = (cmpl *)malloc(sizeof(cmpl)*n);
  115. //
  116. for(i=0;i<n;i++) {
  117. ts[i] = (2.0 * (rand() / (double)RAND_MAX) - 1);
  118. sx[i] = creal(ts[i]);
  119. }
  120. //
  121. forward(ts, fs, n);
  122. struct SleefDFT *p = SleefDFT_init(SLEEF_MODE_DEBUG | SLEEF_MODE_REAL, n);
  123. SleefDFT_execute(p, sy, sx);
  124. //
  125. int success = 1;
  126. for(i=0;i<n/2;i++) {
  127. if (i == 0) {
  128. if (fabs(sy[(2*0+0)] - creal(fs[0 ])) > THRES) success = 0;
  129. if (fabs(sy[(2*0+1)] - creal(fs[n/2])) > THRES) success = 0;
  130. } else {
  131. if (fabs(sy[(2*i+0)] - creal(fs[i])) > THRES) success = 0;
  132. if (fabs(sy[(2*i+1)] - cimag(fs[i])) > THRES) success = 0;
  133. }
  134. }
  135. //
  136. free(fs);
  137. free(ts);
  138. SleefDFT_free(sx);
  139. SleefDFT_free(sy);
  140. SleefDFT_dispose(p);
  141. //
  142. return success;
  143. }
  144. int check_rb(int n) {
  145. int i;
  146. SleefDFT_real *sx = (SleefDFT_real *)SleefDFT_malloc(n * sizeof(SleefDFT_real));
  147. SleefDFT_real *sy = (SleefDFT_real *)SleefDFT_malloc(n * sizeof(SleefDFT_real));
  148. cmpl *ts = (cmpl *)malloc(sizeof(cmpl)*n);
  149. cmpl *fs = (cmpl *)malloc(sizeof(cmpl)*n);
  150. //
  151. for(i=0;i<n/2;i++) {
  152. if (i == 0) {
  153. fs[0 ] = (2.0 * (rand() / (double)RAND_MAX) - 1);
  154. fs[n/2] = (2.0 * (rand() / (double)RAND_MAX) - 1);
  155. } else {
  156. fs[i ] = (2.0 * (rand() / (double)RAND_MAX) - 1) + (2.0 * (rand() / (double)RAND_MAX) - 1) * _Complex_I;
  157. fs[n-i] = conj(fs[i]);
  158. }
  159. }
  160. for(i=0;i<n/2;i++) {
  161. if (i == 0) {
  162. sx[2*0+0] = creal(fs[0 ]);
  163. sx[2*0+1] = creal(fs[n/2]);
  164. } else {
  165. sx[2*i+0] = creal(fs[i]);
  166. sx[2*i+1] = cimag(fs[i]);
  167. }
  168. }
  169. //
  170. backward(fs, ts, n);
  171. struct SleefDFT *p = SleefDFT_init(SLEEF_MODE_DEBUG | SLEEF_MODE_REAL | SLEEF_MODE_BACKWARD, n);
  172. SleefDFT_execute(p, sy, sx);
  173. //
  174. int success = 1;
  175. for(i=0;i<n;i++) {
  176. if (fabs(cimag(ts[i])) > THRES) {
  177. success = 0;
  178. }
  179. if ((fabs(sy[i]*2 - creal(ts[i])) > THRES)) {
  180. success = 0;
  181. }
  182. }
  183. //
  184. free(fs);
  185. free(ts);
  186. SleefDFT_free(sx);
  187. SleefDFT_free(sy);
  188. SleefDFT_dispose(p);
  189. //
  190. return success;
  191. }
  192. int check_arf(int n) {
  193. int i;
  194. SleefDFT_real *sx = (SleefDFT_real *)SleefDFT_malloc(n * sizeof(SleefDFT_real));
  195. SleefDFT_real *sy = (SleefDFT_real *)SleefDFT_malloc(n * sizeof(SleefDFT_real));
  196. cmpl *ts = (cmpl *)malloc(sizeof(cmpl)*n);
  197. cmpl *fs = (cmpl *)malloc(sizeof(cmpl)*n);
  198. //
  199. for(i=0;i<n;i++) {
  200. ts[i] = 2 * (rand() / (SleefDFT_real)RAND_MAX) - 1;
  201. sx[i] = creal(ts[i]);
  202. }
  203. //
  204. backward(ts, fs, n);
  205. struct SleefDFT *p = SleefDFT_init(SLEEF_MODE_REAL | SLEEF_MODE_ALT, n);
  206. SleefDFT_execute(p, sy, sx);
  207. //
  208. int success = 1;
  209. for(i=0;i<n/2;i++) {
  210. if (i == 0) {
  211. if (fabs(sy[(2*0+0)] - creal(fs[0 ])) > THRES) success = 0;
  212. if (fabs(sy[(2*0+1)] - creal(fs[n/2])) > THRES) success = 0;
  213. } else {
  214. if (fabs(sy[(2*i+0)] - creal(fs[i])) > THRES) success = 0;
  215. if (fabs(sy[(2*i+1)] - cimag(fs[i])) > THRES) success = 0;
  216. }
  217. }
  218. //
  219. SleefDFT_free(sx);
  220. SleefDFT_free(sy);
  221. SleefDFT_dispose(p);
  222. //
  223. return success;
  224. }
  225. int check_arb(int n) {
  226. int i;
  227. SleefDFT_real *sx = (SleefDFT_real *)SleefDFT_malloc(n * sizeof(SleefDFT_real));
  228. SleefDFT_real *sy = (SleefDFT_real *)SleefDFT_malloc(n * sizeof(SleefDFT_real));
  229. cmpl *ts = (cmpl *)malloc(sizeof(cmpl)*n);
  230. cmpl *fs = (cmpl *)malloc(sizeof(cmpl)*n);
  231. //
  232. for(i=0;i<n/2;i++) {
  233. if (i == 0) {
  234. fs[0 ] = (2.0 * (rand() / (double)RAND_MAX) - 1);
  235. fs[n/2] = (2.0 * (rand() / (double)RAND_MAX) - 1);
  236. } else {
  237. fs[i ] = (2.0 * (rand() / (double)RAND_MAX) - 1) + (2.0 * (rand() / (double)RAND_MAX) - 1) * _Complex_I;
  238. fs[n-i] = conj(fs[i]);
  239. }
  240. }
  241. for(i=0;i<n/2;i++) {
  242. if (i == 0) {
  243. sx[2*0+0] = creal(fs[0 ]);
  244. sx[2*0+1] = creal(fs[n/2]);
  245. } else {
  246. sx[2*i+0] = creal(fs[i]);
  247. sx[2*i+1] = cimag(fs[i]);
  248. }
  249. }
  250. //
  251. forward(fs, ts, n);
  252. struct SleefDFT *p = SleefDFT_init(SLEEF_MODE_REAL | SLEEF_MODE_BACKWARD | SLEEF_MODE_ALT, n);
  253. SleefDFT_execute(p, sy, sx);
  254. //
  255. int success = 1;
  256. for(i=0;i<n;i++) {
  257. if (fabs(cimag(ts[i])) > THRES) {
  258. success = 0;
  259. }
  260. if ((fabs(sy[i]*2 - creal(ts[i])) > THRES)) {
  261. success = 0;
  262. }
  263. }
  264. //
  265. free(fs);
  266. free(ts);
  267. SleefDFT_free(sx);
  268. SleefDFT_free(sy);
  269. SleefDFT_dispose(p);
  270. //
  271. return success;
  272. }
  273. int main(int argc, char **argv) {
  274. if (argc != 2) {
  275. fprintf(stderr, "%s <log2n>\n", argv[0]);
  276. exit(-1);
  277. }
  278. const int n = 1 << atoi(argv[1]);
  279. srand(time(NULL));
  280. //
  281. printf("complex forward : %s\n", check_cf(n) ? "OK" : "NG");
  282. printf("complex backward : %s\n", check_cb(n) ? "OK" : "NG");
  283. printf("real forward : %s\n", check_rf(n) ? "OK" : "NG");
  284. printf("real backward : %s\n", check_rb(n) ? "OK" : "NG");
  285. printf("real alt forward : %s\n", check_arf(n) ? "OK" : "NG");
  286. printf("real alt backward : %s\n", check_arb(n) ? "OK" : "NG");
  287. exit(0);
  288. }