/plugins/supereq/nsfft-1.00/dfttest/DFTTestNaive.c

https://github.com/Tydus/deadbeef · C · 419 lines · 268 code · 114 blank · 37 comment · 72 complexity · 4ccb22028c38677e35aaa8283a2403e4 MD5 · raw file

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