mxfftd.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883
  1. /*
  2. mxfftd.c: double precision version of mxfft.c
  3. This file is part of the CDP System.
  4. The CDP System is free software; you can redistribute it
  5. and/or modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The CDP System is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the CDP System; if not, write to the Free Software
  14. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  15. 02111-1307 USA
  16. */
  17. /* This program converted from the FORTRAN routines by Singleton in
  18. * Section 1.4 of "Programs for Digital Signal Processing", IEEE Press, 1979.
  19. * Conversion by Trevor Wishart and Keith Henderson, York Univ.
  20. */
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <math.h>
  24. void fft_(double *, double *, int, int, int, int);
  25. void fftmx(double *, double *, int, int, int, int, int,
  26. int*, double *, double *, double *, double *, int *, int[]);
  27. void reals_(double *, double *, int, int);
  28. /*
  29. *-----------------------------------------------------------------------
  30. * subroutine: fft
  31. * multivariate complex fourier transform, computed in place
  32. * using mixed-radix fast fourier transform algorithm.
  33. *-----------------------------------------------------------------------
  34. *
  35. * this is the call from C:
  36. * fft_(anal,banal,&one,&N2,&one,&mtwo);
  37. * CHANGED TO:-
  38. * fft_(anal,banal,one,N2,one,mtwo);
  39. */
  40. void
  41. fft_(double *a, double *b, int nseg, int n, int nspn, int isn)
  42. /* *a, pointer to array 'anal' */
  43. /* *b; pointer to array 'banal' */
  44. {
  45. int nfac[/*16*/32]; /* (2023)WAS 16. These are one bigger than needed */
  46. /* because wish to use Fortran array */
  47. /* index which runs 1 to n, not 0 to n */
  48. int m = 0,
  49. nf,
  50. k,
  51. kt,
  52. ntot,
  53. j,
  54. jj,
  55. maxf, maxp=-1;
  56. /* work space pointers */
  57. double *at, *ck, *bt, *sk;
  58. int *np;
  59. /* reduce the pointers to input arrays - by doing this, FFT uses FORTRAN
  60. indexing but retains compatibility with C arrays */
  61. a--; b--;
  62. /*
  63. * determine the factors of n
  64. */
  65. k=nf=abs(n);
  66. if (nf==1)
  67. return;
  68. nspn=abs(nf*nspn);
  69. ntot=abs(nspn*nseg);
  70. if (isn*ntot == 0) {
  71. printf("\nerror - zero in fft parameters %d %d %d %d",
  72. nseg, n, nspn, isn);
  73. return;
  74. }
  75. for (m=0; !(k%16); nfac[++m]=4,k/=16);
  76. for (j=3,jj=9; jj<=k; j+=2,jj=j*j)
  77. for (; !(k%jj); nfac[++m]=j,k/=jj);
  78. if (k<=4) {
  79. kt = m;
  80. nfac[m+1] = k;
  81. if (k != 1)
  82. m++;
  83. }
  84. else {
  85. if (k%4==0) {
  86. nfac[++m]=2;
  87. k/=4;
  88. }
  89. kt = m;
  90. maxp = (kt+kt+2 > k-1 ? kt+kt+2 : k-1);
  91. for (j=2; j<=k; j=1+((j+1)/2)*2)
  92. if (k%j==0) {
  93. nfac[++m]=j;
  94. k/=j;
  95. }
  96. }
  97. if (m <= kt+1)
  98. maxp = m + kt + 1;
  99. if (m+kt > 15) {
  100. printf("\nerror - fft parameter n has more than 15 factors : %d", n);
  101. return;
  102. }
  103. if (kt!=0) {
  104. j = kt;
  105. while (j)
  106. nfac[++m]=nfac[j--];
  107. }
  108. maxf = nfac[m-kt];
  109. if (kt > 0 && maxf <nfac[kt])
  110. maxf = nfac[kt];
  111. /* allocate workspace - assume no errors! */
  112. at = (double *) calloc(maxf,sizeof(double));
  113. ck = (double *) calloc(maxf,sizeof(double));
  114. bt = (double *) calloc(maxf,sizeof(double));
  115. sk = (double *) calloc(maxf,sizeof(double));
  116. np = (int *) calloc(maxp,sizeof(int));
  117. /* decrement pointers to allow FORTRAN type usage in fftmx */
  118. at--; bt--; ck--; sk--; np--;
  119. /* call fft driver */
  120. fftmx(a,b,ntot,nf,nspn,isn,m,&kt,at,ck,bt,sk,np,nfac);
  121. /* restore pointers before releasing */
  122. at++; bt++; ck++; sk++; np++;
  123. /* release working storage before returning - assume no problems */
  124. free(at);
  125. free(sk);
  126. free(bt);
  127. free(ck);
  128. free(np);
  129. return;
  130. }
  131. /*
  132. *-----------------------------------------------------------------------
  133. * subroutine: fftmx
  134. * called by subroutine 'fft' to compute mixed-radix fourier transform
  135. *-----------------------------------------------------------------------
  136. */
  137. void
  138. fftmx(double *a, double *b, int ntot, int n, int nspan, int isn, int m,
  139. int *kt, double *at, double *ck, double *bt, double *sk, int *np, int nfac[])
  140. {
  141. int i,inc,
  142. j,jc,jf, jj,
  143. k, k1, k2, k3 = 0, k4,
  144. kk,klim,ks,kspan, kspnn,
  145. lim,
  146. maxf,mm,
  147. nn,nt;
  148. double aa, aj, ajm, ajp, ak, akm, akp,
  149. bb, bj, bjm, bjp, bk, bkm, bkp,
  150. c1, c2 = 0.0, c3 = 0.0, c72, cd,
  151. dr,
  152. rad,
  153. sd, s1, s2=0.0, s3=0.0, s72, s120;
  154. double xx; /****** ADDED APRIL 1991 *********/
  155. inc=abs(isn);
  156. nt = inc*ntot;
  157. ks = inc*nspan;
  158. /******************* REPLACED MARCH 29: ***********************
  159. rad = atan((double)1.0);
  160. **************************************************************/
  161. rad = 0.785398163397448278900;
  162. /******************* REPLACED MARCH 29: ***********************
  163. s72 = rad/0.625;
  164. c72 = cos(s72);
  165. s72 = sin(s72);
  166. **************************************************************/
  167. c72 = 0.309016994374947451270;
  168. s72 = 0.951056516295153531190;
  169. /******************* REPLACED MARCH 29: ***********************
  170. s120 = sqrt((double)0.75);
  171. **************************************************************/
  172. s120 = 0.866025403784438707600;
  173. /* scale by 1/n for isn > 0 ( reverse transform ) */
  174. if (isn < 0) {
  175. s72 = -s72;
  176. s120 = -s120;
  177. rad = -rad;}
  178. else {
  179. ak = 1.0/(double)n;
  180. for (j=1; j<=nt;j += inc) {
  181. a[j] *= (double)ak;
  182. b[j] *= (double)ak;
  183. }
  184. }
  185. kspan = ks;
  186. nn = nt - inc;
  187. jc = ks/n;
  188. /* sin, cos values are re-initialised each lim steps */
  189. lim = 32;
  190. klim = lim * jc;
  191. i = 0;
  192. jf = 0;
  193. maxf = m - (*kt);
  194. maxf = nfac[maxf];
  195. if ((*kt) > 0 && maxf < nfac[*kt])
  196. maxf = nfac[*kt];
  197. /*
  198. * compute fourier transform
  199. */
  200. lbl40:
  201. dr = (8.0 * (double)jc)/((double)kspan);
  202. /*************************** APRIL 1991 POW & POW2 not WORKING.. REPLACE *******
  203. cd = 2.0 * (pow2 ( sin((double)0.5 * dr * rad)) );
  204. *******************************************************************************/
  205. xx = sin((double)0.5 * dr * rad);
  206. cd = 2.0 * xx * xx;
  207. sd = sin(dr * rad);
  208. kk = 1;
  209. if (nfac[++i]!=2) goto lbl110;
  210. /*
  211. * transform for factor of 2 (including rotation factor)
  212. */
  213. kspan /= 2;
  214. k1 = kspan + 2;
  215. do {
  216. do {
  217. k2 = kk + kspan;
  218. ak = a[k2];
  219. bk = b[k2];
  220. a[k2] = (a[kk]) - (double)ak;
  221. b[k2] = (b[kk]) - (double)bk;
  222. a[kk] = (a[kk]) + (double)ak;
  223. b[kk] = (b[kk]) + (double)bk;
  224. kk = k2 + kspan;
  225. } while (kk <= nn);
  226. kk -= nn;
  227. } while (kk <= jc);
  228. if (kk > kspan) goto lbl350;
  229. lbl60:
  230. c1 = 1.0 - cd;
  231. s1 = sd;
  232. mm = (k1/2 < klim ? k1/2 :klim);
  233. goto lbl80;
  234. lbl70:
  235. ak = c1 - ((cd*c1)+(sd*s1));
  236. s1 = ((sd*c1)-(cd*s1)) + s1;
  237. c1 = ak;
  238. lbl80:
  239. do {
  240. do {
  241. k2 = kk + kspan;
  242. ak = a[kk] - a[k2];
  243. bk = b[kk] - b[k2];
  244. a[kk] = a[kk] + a[k2];
  245. b[kk] = b[kk] + b[k2];
  246. a[k2] = (double)((c1 * ak) - (s1 * bk));
  247. b[k2] = (double)((s1 * ak) + (c1 * bk));
  248. kk = k2 + kspan;
  249. } while (kk < nt);
  250. k2 = kk - nt;
  251. c1 = -c1;
  252. kk = k1 - k2;
  253. } while (kk > k2);
  254. kk += jc;
  255. if (kk <= mm) goto lbl70;
  256. if (kk < k2) goto lbl90;
  257. k1 += (inc + inc);
  258. kk = ((k1-kspan)/2) + jc;
  259. if (kk <= (jc+jc)) goto lbl60;
  260. goto lbl40;
  261. lbl90:
  262. s1 = ((double)((kk-1)/jc)) * dr * rad;
  263. c1 = cos(s1);
  264. s1 = sin(s1);
  265. mm = (k1/2 < mm+klim ? k1/2 : mm+klim);
  266. goto lbl80;
  267. /*
  268. * transform for factor of 3 (optional code)
  269. */
  270. lbl100:
  271. k1 = kk + kspan;
  272. k2 = k1 + kspan;
  273. ak = a[kk];
  274. bk = b[kk];
  275. aj = a[k1] + a[k2];
  276. bj = b[k1] + b[k2];
  277. a[kk] = (double)(ak + aj);
  278. b[kk] = (double)(bk + bj);
  279. ak += (-0.5 * aj);
  280. bk += (-0.5 * bj);
  281. aj = (a[k1] - a[k2]) * s120;
  282. bj = (b[k1] - b[k2]) * s120;
  283. a[k1] = (double)(ak - bj);
  284. b[k1] = (double)(bk + aj);
  285. a[k2] = (double)(ak + bj);
  286. b[k2] = (double)(bk - aj);
  287. kk = k2 + kspan;
  288. if (kk < nn) goto lbl100;
  289. kk -= nn;
  290. if (kk <= kspan) goto lbl100;
  291. goto lbl290;
  292. /*
  293. * transform for factor of 4
  294. */
  295. lbl110:
  296. if (nfac[i] != 4) goto lbl230;
  297. kspnn = kspan;
  298. kspan = kspan/4;
  299. lbl120:
  300. c1 = 1.0;
  301. s1 = 0;
  302. mm = (kspan < klim ? kspan : klim);
  303. goto lbl150;
  304. lbl130:
  305. c2 = c1 - ((cd*c1)+(sd*s1));
  306. s1 = ((sd*c1)-(cd*s1)) + s1;
  307. /*
  308. * the following three statements compensate for truncation
  309. * error. if rounded arithmetic is used, substitute
  310. * c1=c2
  311. *
  312. * c1 = (0.5/(pow2(c2)+pow2(s1))) + 0.5;
  313. * s1 = c1*s1;
  314. * c1 = c1*c2;
  315. */
  316. c1 = c2;
  317. lbl140:
  318. c2 = (c1 * c1) - (s1 * s1);
  319. s2 = c1 * s1 * 2.0;
  320. c3 = (c2 * c1) - (s2 * s1);
  321. s3 = (c2 * s1) + (s2 * c1);
  322. lbl150:
  323. k1 = kk + kspan;
  324. k2 = k1 + kspan;
  325. k3 = k2 + kspan;
  326. akp = a[kk] + a[k2];
  327. akm = a[kk] - a[k2];
  328. ajp = a[k1] + a[k3];
  329. ajm = a[k1] - a[k3];
  330. a[kk] = (double)(akp + ajp);
  331. ajp = akp - ajp;
  332. bkp = b[kk] + b[k2];
  333. bkm = b[kk] - b[k2];
  334. bjp = b[k1] + b[k3];
  335. bjm = b[k1] - b[k3];
  336. b[kk] = (double)(bkp + bjp);
  337. bjp = bkp - bjp;
  338. if (isn < 0) goto lbl180;
  339. akp = akm - bjm;
  340. akm = akm + bjm;
  341. bkp = bkm + ajm;
  342. bkm = bkm - ajm;
  343. if (s1 == 0.0) goto lbl190;
  344. lbl160:
  345. a[k1] = (double)((akp*c1) - (bkp*s1));
  346. b[k1] = (double)((akp*s1) + (bkp*c1));
  347. a[k2] = (double)((ajp*c2) - (bjp*s2));
  348. b[k2] = (double)((ajp*s2) + (bjp*c2));
  349. a[k3] = (double)((akm*c3) - (bkm*s3));
  350. b[k3] = (double)((akm*s3) + (bkm*c3));
  351. kk = k3 + kspan;
  352. if (kk <= nt) goto lbl150;
  353. lbl170:
  354. kk -= (nt - jc);
  355. if (kk <= mm) goto lbl130;
  356. if (kk < kspan) goto lbl200;
  357. kk -= (kspan - inc);
  358. if (kk <= jc) goto lbl120;
  359. if (kspan==jc) goto lbl350;
  360. goto lbl40;
  361. lbl180:
  362. akp = akm + bjm;
  363. akm = akm - bjm;
  364. bkp = bkm - ajm;
  365. bkm = bkm + ajm;
  366. if (s1 != 0.0) goto lbl160;
  367. lbl190:
  368. a[k1] = (double)akp;
  369. b[k1] = (double)bkp;
  370. a[k2] = (double)ajp;
  371. b[k2] = (double)bjp;
  372. a[k3] = (double)akm;
  373. b[k3] = (double)bkm;
  374. kk = k3 + kspan;
  375. if (kk <= nt) goto lbl150;
  376. goto lbl170;
  377. lbl200:
  378. s1 = ((double)((kk-1)/jc)) * dr * rad;
  379. c1 = cos(s1);
  380. s1 = sin(s1);
  381. mm = (kspan < mm+klim ? kspan : mm+klim);
  382. goto lbl140;
  383. /*
  384. * transform for factor of 5 (optional code)
  385. */
  386. lbl210:
  387. c2 = (c72*c72) - (s72*s72);
  388. s2 = 2.0 * c72 * s72;
  389. lbl220:
  390. k1 = kk + kspan;
  391. k2 = k1 + kspan;
  392. k3 = k2 + kspan;
  393. k4 = k3 + kspan;
  394. akp = a[k1] + a[k4];
  395. akm = a[k1] - a[k4];
  396. bkp = b[k1] + b[k4];
  397. bkm = b[k1] - b[k4];
  398. ajp = a[k2] + a[k3];
  399. ajm = a[k2] - a[k3];
  400. bjp = b[k2] + b[k3];
  401. bjm = b[k2] - b[k3];
  402. aa = a[kk];
  403. bb = b[kk];
  404. a[kk] = (double)(aa + akp + ajp);
  405. b[kk] = (double)(bb + bkp + bjp);
  406. ak = (akp*c72) + (ajp*c2) + aa;
  407. bk = (bkp*c72) + (bjp*c2) + bb;
  408. aj = (akm*s72) + (ajm*s2);
  409. bj = (bkm*s72) + (bjm*s2);
  410. a[k1] = (double)(ak - bj);
  411. a[k4] = (double)(ak + bj);
  412. b[k1] = (double)(bk + aj);
  413. b[k4] = (double)(bk - aj);
  414. ak = (akp*c2) + (ajp*c72) + aa;
  415. bk = (bkp*c2) + (bjp*c72) + bb;
  416. aj = (akm*s2) - (ajm*s72);
  417. bj = (bkm*s2) - (bjm*s72);
  418. a[k2] = (double)(ak - bj);
  419. a[k3] = (double)(ak + bj);
  420. b[k2] = (double)(bk + aj);
  421. b[k3] = (double)(bk - aj);
  422. kk = k4 + kspan;
  423. if (kk < nn) goto lbl220;
  424. kk -= nn;
  425. if (kk <= kspan) goto lbl220;
  426. goto lbl290;
  427. /*
  428. * transform for odd factors
  429. */
  430. lbl230:
  431. k = nfac[i];
  432. kspnn = kspan;
  433. kspan /= k;
  434. if (k==3) goto lbl100;
  435. if (k==5) goto lbl210;
  436. if (k==jf) goto lbl250;
  437. jf = k;
  438. s1 = rad/(((double)(k))/8.0);
  439. c1 = cos(s1);
  440. s1 = sin(s1);
  441. ck[jf] = 1.0;
  442. sk[jf] = 0.0;
  443. for (j=1; j<k ; j++) {
  444. ck[j] = (double)((ck[k])*c1 + (sk[k])*s1);
  445. sk[j] = (double)((ck[k])*s1 - (sk[k])*c1);
  446. k--;
  447. ck[k] = ck[j];
  448. sk[k] = -(sk[j]);
  449. }
  450. lbl250:
  451. k1 = kk;
  452. k2 = kk + kspnn;
  453. aa = a[kk];
  454. bb = b[kk];
  455. ak = aa;
  456. bk = bb;
  457. j = 1;
  458. k1 += kspan;
  459. do {
  460. k2 -= kspan;
  461. j++;
  462. at[j] = a[k1] + a[k2];
  463. ak = at[j] + ak;
  464. bt[j] = b[k1] + b[k2];
  465. bk = bt[j] + bk;
  466. j++;
  467. at[j] = a[k1] - a[k2];
  468. bt[j] = b[k1] - b[k2];
  469. k1 += kspan;
  470. } while (k1 < k2);
  471. a[kk] = (double)ak;
  472. b[kk] = (double)bk;
  473. k1 = kk;
  474. k2 = kk + kspnn;
  475. j = 1;
  476. lbl270:
  477. k1 += kspan;
  478. k2 -= kspan;
  479. jj = j;
  480. ak = aa;
  481. bk = bb;
  482. aj = 0.0;
  483. bj = 0.0;
  484. k = 1;
  485. do {
  486. k++;
  487. ak = (at[k] * ck[jj]) + ak;
  488. bk = (bt[k] * ck[jj]) + bk;
  489. k++;
  490. aj = (at[k] * sk[jj]) + aj;
  491. bj = (bt[k] * sk[jj]) + bj;
  492. jj += j;
  493. if (jj > jf)
  494. jj -= jf;
  495. } while (k < jf);
  496. k = jf - j;
  497. a[k1] = (double)(ak - bj);
  498. b[k1] = (double)(bk + aj);
  499. a[k2] = (double)(ak + bj);
  500. b[k2] = (double)(bk - aj);
  501. j++;
  502. if (j < k) goto lbl270;
  503. kk += kspnn;
  504. if (kk <= nn) goto lbl250;
  505. kk -= nn;
  506. if (kk<=kspan) goto lbl250;
  507. /*
  508. * multiply by rotation factor (except for factors of 2 and 4)
  509. */
  510. lbl290:
  511. if (i==m) goto lbl350;
  512. kk = jc + 1;
  513. lbl300:
  514. c2 = 1.0 - cd;
  515. s1 = sd;
  516. mm = (kspan < klim ? kspan : klim);
  517. goto lbl320;
  518. lbl310:
  519. c2 = c1 - ((cd*c1) + (sd*s1));
  520. s1 = s1 + ((sd*c1) - (cd*s1));
  521. lbl320:
  522. c1 = c2;
  523. s2 = s1;
  524. kk += kspan;
  525. lbl330:
  526. ak = a[kk];
  527. a[kk] = (double)((c2*ak) - (s2 * b[kk]));
  528. b[kk] = (double)((s2*ak) + (c2 * b[kk]));
  529. kk += kspnn;
  530. if (kk <= nt) goto lbl330;
  531. ak = s1*s2;
  532. s2 = (s1*c2) + (c1*s2);
  533. c2 = (c1*c2) - ak;
  534. kk -= (nt - kspan);
  535. if (kk <= kspnn) goto lbl330;
  536. kk -= (kspnn - jc);
  537. if (kk <= mm) goto lbl310;
  538. if (kk < kspan) goto lbl340;
  539. kk -= (kspan - jc - inc);
  540. if (kk <= (jc+jc)) goto lbl300;
  541. goto lbl40;
  542. lbl340:
  543. s1 = ((double)((kk-1)/jc)) * dr * rad;
  544. c2 = cos(s1);
  545. s1 = sin(s1);
  546. mm = (kspan < mm+klim ? kspan :mm+klim);
  547. goto lbl320;
  548. /*
  549. * permute the results to normal order---done in two stages
  550. * permutation for square factors of n
  551. */
  552. lbl350:
  553. np[1] = ks;
  554. if (!(*kt)) goto lbl440;
  555. k = *kt + *kt + 1;
  556. if (m < k)
  557. k--;
  558. np[k+1] = jc;
  559. for (j=1; j < k; j++,k--) {
  560. np[j+1] = np[j] / nfac[j];
  561. np[k] = np[k+1] * nfac[j];
  562. }
  563. k3 = np[k+1];
  564. kspan = np[2];
  565. kk = jc + 1;
  566. k2 = kspan + 1;
  567. j = 1;
  568. if (n != ntot) goto lbl400;
  569. /*
  570. * permutation for single-variate transform (optional code)
  571. */
  572. lbl370:
  573. do {
  574. ak = a[kk];
  575. a[kk] = a[k2];
  576. a[k2] = (double)ak;
  577. bk = b[kk];
  578. b[kk] = b[k2];
  579. b[k2] = (double)bk;
  580. kk += inc;
  581. k2 += kspan;
  582. } while (k2 < ks);
  583. lbl380:
  584. do {
  585. k2 -= np[j++];
  586. k2 += np[j+1];
  587. } while (k2 > np[j]);
  588. j = 1;
  589. lbl390:
  590. if (kk < k2) {
  591. goto lbl370;
  592. }
  593. kk += inc;
  594. k2 += kspan;
  595. if (k2 < ks) goto lbl390;
  596. if (kk < ks) goto lbl380;
  597. jc = k3;
  598. goto lbl440;
  599. /*
  600. * permutation for multivariate transform
  601. */
  602. lbl400:
  603. do {
  604. do {
  605. k = kk + jc;
  606. do {
  607. ak = a[kk];
  608. a[kk] = a[k2];
  609. a[k2] = (double)ak;
  610. bk = b[kk];
  611. b[kk] = b[k2];
  612. b[k2] = (double)bk;
  613. kk += inc;
  614. k2 += inc;
  615. } while (kk < k);
  616. kk += (ks - jc);
  617. k2 += (ks - jc);
  618. } while (kk < nt);
  619. k2 -= (nt - kspan);
  620. kk -= (nt - jc);
  621. } while (k2 < ks);
  622. lbl420:
  623. do {
  624. k2 -= np[j++];
  625. k2 += np[j+1];
  626. } while (k2 > np[j]);
  627. j = 1;
  628. lbl430:
  629. if (kk < k2) goto lbl400;
  630. kk += jc;
  631. k2 += kspan;
  632. if (k2 < ks) goto lbl430;
  633. if (kk < ks) goto lbl420;
  634. jc = k3;
  635. lbl440:
  636. if ((2*(*kt))+1 >= m)
  637. return;
  638. kspnn = *(np + *(kt) + 1);
  639. j = m - *kt;
  640. nfac[j+1] = 1;
  641. lbl450:
  642. nfac[j] = nfac[j] * nfac[j+1];
  643. j--;
  644. if (j != *kt) goto lbl450;
  645. *kt = *(kt) + 1;
  646. nn = nfac[*kt] - 1;
  647. jj = 0;
  648. j = 0;
  649. goto lbl480;
  650. lbl460:
  651. jj -= k2;
  652. k2 = kk;
  653. kk = nfac[++k];
  654. lbl470:
  655. jj += kk;
  656. if (jj >= k2) goto lbl460;
  657. np[j] = jj;
  658. lbl480:
  659. k2 = nfac[*kt];
  660. k = *kt + 1;
  661. kk = nfac[k];
  662. j++;
  663. if (j <= nn) goto lbl470;
  664. /* Determine permutation cycles of length greater than 1 */
  665. j = 0;
  666. goto lbl500;
  667. lbl490:
  668. k = kk;
  669. kk = np[k];
  670. np[k] = -kk;
  671. if (kk != j) goto lbl490;
  672. k3 = kk;
  673. lbl500:
  674. kk = np[++j];
  675. if (kk < 0) goto lbl500;
  676. if (kk != j) goto lbl490;
  677. np[j] = -j;
  678. if (j != nn) goto lbl500;
  679. maxf *= inc;
  680. /* Perform reordering following permutation cycles */
  681. goto lbl570;
  682. lbl510:
  683. j--;
  684. if (np[j] < 0) goto lbl510;
  685. jj = jc;
  686. lbl520:
  687. kspan = jj;
  688. if (jj > maxf)
  689. kspan = maxf;
  690. jj -= kspan;
  691. k = np[j];
  692. kk = (jc*k) + i + jj;
  693. k1 = kk + kspan;
  694. k2 = 0;
  695. lbl530:
  696. k2++;
  697. at[k2] = a[k1];
  698. bt[k2] = b[k1];
  699. k1 -= inc;
  700. if (k1 != kk) goto lbl530;
  701. lbl540:
  702. k1 = kk + kspan;
  703. k2 = k1 - (jc * (k + np[k]));
  704. k = -(np[k]);
  705. lbl550:
  706. a[k1] = a[k2];
  707. b[k1] = b[k2];
  708. k1 -= inc;
  709. k2 -= inc;
  710. if (k1 != kk) goto lbl550;
  711. kk = k2;
  712. if (k != j) goto lbl540;
  713. k1 = kk + kspan;
  714. k2 = 0;
  715. lbl560:
  716. k2++;
  717. a[k1] = at[k2];
  718. b[k1] = bt[k2];
  719. k1 -= inc;
  720. if (k1 != kk) goto lbl560;
  721. if (jj) goto lbl520;
  722. if (j != 1) goto lbl510;
  723. lbl570:
  724. j = k3 + 1;
  725. nt -= kspnn;
  726. i = nt - inc + 1;
  727. if (nt >= 0) goto lbl510;
  728. return;
  729. }
  730. /*
  731. *-----------------------------------------------------------------------
  732. * subroutine:
  733. reals
  734. * used with 'fft' to compute fourier transform or inverse for real data
  735. *-----------------------------------------------------------------------
  736. * this is the call from C:
  737. * reals_(anal,banal,N2,mtwo);
  738. * which has been changed from CARL call
  739. * reals_(anal,banal,&N2,&mtwo);
  740. */
  741. void
  742. reals_(double *a, double *b, int n, int isn)
  743. /* *a, a refers to an array of floats 'anal' */
  744. /* *b; b refers to an array of floats 'banal' */
  745. /* See IEEE book for a long comment here on usage */
  746. {
  747. int inc,
  748. j,
  749. k,
  750. lim,
  751. mm,ml,
  752. nf,nk,nh;
  753. double aa,ab,
  754. ba,bb,
  755. cd,cn,
  756. dr,
  757. em,
  758. rad,re,
  759. sd,sn;
  760. double xx; /******* ADDED APRIL 1991 ******/
  761. /* adjust input array pointers (called from C) */
  762. a--; b--;
  763. inc=abs(isn);
  764. nf=abs(n);
  765. if (nf*isn==0) {
  766. printf("\nerror - zero in reals parameters : %d : %d ",n,isn);
  767. return;
  768. }
  769. nk = (nf*inc) + 2;
  770. nh = nk/2;
  771. /*****************************
  772. rad = atan((double)1.0);
  773. ******************************/
  774. rad = 0.785398163397448278900;
  775. dr = -4.0/(double)(nf);
  776. /********************************** POW2 REMOVED APRIL 1991 *****************
  777. cd = 2.0 * (pow2(sin((double)0.5 * dr * rad)));
  778. *****************************************************************************/
  779. xx = sin((double)0.5 * dr * rad);
  780. cd = 2.0 * xx * xx;
  781. sd = sin(dr * rad);
  782. /*
  783. * sin,cos values are re-initialised each lim steps
  784. */
  785. lim = 32;
  786. mm = lim;
  787. ml = 0;
  788. sn = 0.0;
  789. if (isn<0) {
  790. cn = 1.0;
  791. a[nk-1] = a[1];
  792. b[nk-1] = b[1]; }
  793. else {
  794. cn = -1.0;
  795. sd = -sd;
  796. }
  797. for (j=1;j<=nh;j+=inc) {
  798. k = nk - j;
  799. aa = a[j] + a[k];
  800. ab = a[j] - a[k];
  801. ba = b[j] + b[k];
  802. bb = b[j] - b[k];
  803. re = (cn*ba) + (sn*ab);
  804. em = (sn*ba) - (cn*ab);
  805. b[k] = (double)((em-bb)*0.5);
  806. b[j] = (double)((em+bb)*0.5);
  807. a[k] = (double)((aa-re)*0.5);
  808. a[j] = (double)((aa+re)*0.5);
  809. ml++;
  810. if (ml!=mm) {
  811. aa = cn - ((cd*cn)+(sd*sn));
  812. sn = ((sd*cn) - (cd*sn)) + sn;
  813. cn = aa;}
  814. else {
  815. mm +=lim;
  816. sn = ((double)ml) * dr * rad;
  817. cn = cos(sn);
  818. if (isn>0)
  819. cn = -cn;
  820. sn = sin(sn);
  821. }
  822. }
  823. return;
  824. }