fftsg.c 78 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975
  1. /* This file is copied from
  2. *
  3. * https://www.kurims.kyoto-u.ac.jp/~ooura/fft.html
  4. *
  5. * Copyright Takuya OOURA, 1996-2001
  6. *
  7. * You may use, copy, modify and distribute this code for any
  8. * purpose (include commercial use) and without fee. Please refer to
  9. * this package when you modify this code.
  10. */
  11. /*
  12. Fast Fourier/Cosine/Sine Transform
  13. dimension :one
  14. data length :power of 2
  15. decimation :frequency
  16. radix :split-radix
  17. data :inplace
  18. table :use
  19. functions
  20. cdft: Complex Discrete Fourier Transform
  21. rdft: Real Discrete Fourier Transform
  22. ddct: Discrete Cosine Transform
  23. ddst: Discrete Sine Transform
  24. dfct: Cosine Transform of RDFT (Real Symmetric DFT)
  25. dfst: Sine Transform of RDFT (Real Anti-symmetric DFT)
  26. function prototypes
  27. void cdft(int, int, double *, int *, double *);
  28. void rdft(int, int, double *, int *, double *);
  29. void ddct(int, int, double *, int *, double *);
  30. void ddst(int, int, double *, int *, double *);
  31. void dfct(int, double *, double *, int *, double *);
  32. void dfst(int, double *, double *, int *, double *);
  33. macro definitions
  34. USE_CDFT_PTHREADS : default=not defined
  35. CDFT_THREADS_BEGIN_N : must be >= 512, default=8192
  36. CDFT_4THREADS_BEGIN_N : must be >= 512, default=65536
  37. USE_CDFT_WINTHREADS : default=not defined
  38. CDFT_THREADS_BEGIN_N : must be >= 512, default=32768
  39. CDFT_4THREADS_BEGIN_N : must be >= 512, default=524288
  40. -------- Complex DFT (Discrete Fourier Transform) --------
  41. [definition]
  42. <case1>
  43. X[k] = sum_j=0^n-1 x[j]*exp(2*pi*i*j*k/n), 0<=k<n
  44. <case2>
  45. X[k] = sum_j=0^n-1 x[j]*exp(-2*pi*i*j*k/n), 0<=k<n
  46. (notes: sum_j=0^n-1 is a summation from j=0 to n-1)
  47. [usage]
  48. <case1>
  49. ip[0] = 0; // first time only
  50. cdft(2*n, 1, a, ip, w);
  51. <case2>
  52. ip[0] = 0; // first time only
  53. cdft(2*n, -1, a, ip, w);
  54. [parameters]
  55. 2*n :data length (int)
  56. n >= 1, n = power of 2
  57. a[0...2*n-1] :input/output data (double *)
  58. input data
  59. a[2*j] = Re(x[j]),
  60. a[2*j+1] = Im(x[j]), 0<=j<n
  61. output data
  62. a[2*k] = Re(X[k]),
  63. a[2*k+1] = Im(X[k]), 0<=k<n
  64. ip[0...*] :work area for bit reversal (int *)
  65. length of ip >= 2+sqrt(n)
  66. strictly,
  67. length of ip >=
  68. 2+(1<<(int)(log(n+0.5)/log(2))/2).
  69. ip[0],ip[1] are pointers of the cos/sin table.
  70. w[0...n/2-1] :cos/sin table (double *)
  71. w[],ip[] are initialized if ip[0] == 0.
  72. [remark]
  73. Inverse of
  74. cdft(2*n, -1, a, ip, w);
  75. is
  76. cdft(2*n, 1, a, ip, w);
  77. for (j = 0; j <= 2 * n - 1; j++) {
  78. a[j] *= 1.0 / n;
  79. }
  80. .
  81. -------- Real DFT / Inverse of Real DFT --------
  82. [definition]
  83. <case1> RDFT
  84. R[k] = sum_j=0^n-1 a[j]*cos(2*pi*j*k/n), 0<=k<=n/2
  85. I[k] = sum_j=0^n-1 a[j]*sin(2*pi*j*k/n), 0<k<n/2
  86. <case2> IRDFT (excluding scale)
  87. a[k] = (R[0] + R[n/2]*cos(pi*k))/2 +
  88. sum_j=1^n/2-1 R[j]*cos(2*pi*j*k/n) +
  89. sum_j=1^n/2-1 I[j]*sin(2*pi*j*k/n), 0<=k<n
  90. [usage]
  91. <case1>
  92. ip[0] = 0; // first time only
  93. rdft(n, 1, a, ip, w);
  94. <case2>
  95. ip[0] = 0; // first time only
  96. rdft(n, -1, a, ip, w);
  97. [parameters]
  98. n :data length (int)
  99. n >= 2, n = power of 2
  100. a[0...n-1] :input/output data (double *)
  101. <case1>
  102. output data
  103. a[2*k] = R[k], 0<=k<n/2
  104. a[2*k+1] = I[k], 0<k<n/2
  105. a[1] = R[n/2]
  106. <case2>
  107. input data
  108. a[2*j] = R[j], 0<=j<n/2
  109. a[2*j+1] = I[j], 0<j<n/2
  110. a[1] = R[n/2]
  111. ip[0...*] :work area for bit reversal (int *)
  112. length of ip >= 2+sqrt(n/2)
  113. strictly,
  114. length of ip >=
  115. 2+(1<<(int)(log(n/2+0.5)/log(2))/2).
  116. ip[0],ip[1] are pointers of the cos/sin table.
  117. w[0...n/2-1] :cos/sin table (double *)
  118. w[],ip[] are initialized if ip[0] == 0.
  119. [remark]
  120. Inverse of
  121. rdft(n, 1, a, ip, w);
  122. is
  123. rdft(n, -1, a, ip, w);
  124. for (j = 0; j <= n - 1; j++) {
  125. a[j] *= 2.0 / n;
  126. }
  127. .
  128. -------- DCT (Discrete Cosine Transform) / Inverse of DCT --------
  129. [definition]
  130. <case1> IDCT (excluding scale)
  131. C[k] = sum_j=0^n-1 a[j]*cos(pi*j*(k+1/2)/n), 0<=k<n
  132. <case2> DCT
  133. C[k] = sum_j=0^n-1 a[j]*cos(pi*(j+1/2)*k/n), 0<=k<n
  134. [usage]
  135. <case1>
  136. ip[0] = 0; // first time only
  137. ddct(n, 1, a, ip, w);
  138. <case2>
  139. ip[0] = 0; // first time only
  140. ddct(n, -1, a, ip, w);
  141. [parameters]
  142. n :data length (int)
  143. n >= 2, n = power of 2
  144. a[0...n-1] :input/output data (double *)
  145. output data
  146. a[k] = C[k], 0<=k<n
  147. ip[0...*] :work area for bit reversal (int *)
  148. length of ip >= 2+sqrt(n/2)
  149. strictly,
  150. length of ip >=
  151. 2+(1<<(int)(log(n/2+0.5)/log(2))/2).
  152. ip[0],ip[1] are pointers of the cos/sin table.
  153. w[0...n*5/4-1] :cos/sin table (double *)
  154. w[],ip[] are initialized if ip[0] == 0.
  155. [remark]
  156. Inverse of
  157. ddct(n, -1, a, ip, w);
  158. is
  159. a[0] *= 0.5;
  160. ddct(n, 1, a, ip, w);
  161. for (j = 0; j <= n - 1; j++) {
  162. a[j] *= 2.0 / n;
  163. }
  164. .
  165. -------- DST (Discrete Sine Transform) / Inverse of DST --------
  166. [definition]
  167. <case1> IDST (excluding scale)
  168. S[k] = sum_j=1^n A[j]*sin(pi*j*(k+1/2)/n), 0<=k<n
  169. <case2> DST
  170. S[k] = sum_j=0^n-1 a[j]*sin(pi*(j+1/2)*k/n), 0<k<=n
  171. [usage]
  172. <case1>
  173. ip[0] = 0; // first time only
  174. ddst(n, 1, a, ip, w);
  175. <case2>
  176. ip[0] = 0; // first time only
  177. ddst(n, -1, a, ip, w);
  178. [parameters]
  179. n :data length (int)
  180. n >= 2, n = power of 2
  181. a[0...n-1] :input/output data (double *)
  182. <case1>
  183. input data
  184. a[j] = A[j], 0<j<n
  185. a[0] = A[n]
  186. output data
  187. a[k] = S[k], 0<=k<n
  188. <case2>
  189. output data
  190. a[k] = S[k], 0<k<n
  191. a[0] = S[n]
  192. ip[0...*] :work area for bit reversal (int *)
  193. length of ip >= 2+sqrt(n/2)
  194. strictly,
  195. length of ip >=
  196. 2+(1<<(int)(log(n/2+0.5)/log(2))/2).
  197. ip[0],ip[1] are pointers of the cos/sin table.
  198. w[0...n*5/4-1] :cos/sin table (double *)
  199. w[],ip[] are initialized if ip[0] == 0.
  200. [remark]
  201. Inverse of
  202. ddst(n, -1, a, ip, w);
  203. is
  204. a[0] *= 0.5;
  205. ddst(n, 1, a, ip, w);
  206. for (j = 0; j <= n - 1; j++) {
  207. a[j] *= 2.0 / n;
  208. }
  209. .
  210. -------- Cosine Transform of RDFT (Real Symmetric DFT) --------
  211. [definition]
  212. C[k] = sum_j=0^n a[j]*cos(pi*j*k/n), 0<=k<=n
  213. [usage]
  214. ip[0] = 0; // first time only
  215. dfct(n, a, t, ip, w);
  216. [parameters]
  217. n :data length - 1 (int)
  218. n >= 2, n = power of 2
  219. a[0...n] :input/output data (double *)
  220. output data
  221. a[k] = C[k], 0<=k<=n
  222. t[0...n/2] :work area (double *)
  223. ip[0...*] :work area for bit reversal (int *)
  224. length of ip >= 2+sqrt(n/4)
  225. strictly,
  226. length of ip >=
  227. 2+(1<<(int)(log(n/4+0.5)/log(2))/2).
  228. ip[0],ip[1] are pointers of the cos/sin table.
  229. w[0...n*5/8-1] :cos/sin table (double *)
  230. w[],ip[] are initialized if ip[0] == 0.
  231. [remark]
  232. Inverse of
  233. a[0] *= 0.5;
  234. a[n] *= 0.5;
  235. dfct(n, a, t, ip, w);
  236. is
  237. a[0] *= 0.5;
  238. a[n] *= 0.5;
  239. dfct(n, a, t, ip, w);
  240. for (j = 0; j <= n; j++) {
  241. a[j] *= 2.0 / n;
  242. }
  243. .
  244. -------- Sine Transform of RDFT (Real Anti-symmetric DFT) --------
  245. [definition]
  246. S[k] = sum_j=1^n-1 a[j]*sin(pi*j*k/n), 0<k<n
  247. [usage]
  248. ip[0] = 0; // first time only
  249. dfst(n, a, t, ip, w);
  250. [parameters]
  251. n :data length + 1 (int)
  252. n >= 2, n = power of 2
  253. a[0...n-1] :input/output data (double *)
  254. output data
  255. a[k] = S[k], 0<k<n
  256. (a[0] is used for work area)
  257. t[0...n/2-1] :work area (double *)
  258. ip[0...*] :work area for bit reversal (int *)
  259. length of ip >= 2+sqrt(n/4)
  260. strictly,
  261. length of ip >=
  262. 2+(1<<(int)(log(n/4+0.5)/log(2))/2).
  263. ip[0],ip[1] are pointers of the cos/sin table.
  264. w[0...n*5/8-1] :cos/sin table (double *)
  265. w[],ip[] are initialized if ip[0] == 0.
  266. [remark]
  267. Inverse of
  268. dfst(n, a, t, ip, w);
  269. is
  270. dfst(n, a, t, ip, w);
  271. for (j = 1; j <= n - 1; j++) {
  272. a[j] *= 2.0 / n;
  273. }
  274. .
  275. Appendix :
  276. The cos/sin table is recalculated when the larger table required.
  277. w[] and ip[] are compatible with all routines.
  278. */
  279. void rdft(int n, int isgn, double *a, int *ip, double *w)
  280. {
  281. void makewt(int nw, int *ip, double *w);
  282. void makect(int nc, int *ip, double *c);
  283. void cftfsub(int n, double *a, int *ip, int nw, double *w);
  284. void cftbsub(int n, double *a, int *ip, int nw, double *w);
  285. void rftfsub(int n, double *a, int nc, double *c);
  286. void rftbsub(int n, double *a, int nc, double *c);
  287. int nw, nc;
  288. double xi;
  289. nw = ip[0];
  290. if (n > (nw << 2)) {
  291. nw = n >> 2;
  292. makewt(nw, ip, w);
  293. }
  294. nc = ip[1];
  295. if (n > (nc << 2)) {
  296. nc = n >> 2;
  297. makect(nc, ip, w + nw);
  298. }
  299. if (isgn >= 0) {
  300. if (n > 4) {
  301. cftfsub(n, a, ip, nw, w);
  302. rftfsub(n, a, nc, w + nw);
  303. } else if (n == 4) {
  304. cftfsub(n, a, ip, nw, w);
  305. }
  306. xi = a[0] - a[1];
  307. a[0] += a[1];
  308. a[1] = xi;
  309. } else {
  310. a[1] = 0.5 * (a[0] - a[1]);
  311. a[0] -= a[1];
  312. if (n > 4) {
  313. rftbsub(n, a, nc, w + nw);
  314. cftbsub(n, a, ip, nw, w);
  315. } else if (n == 4) {
  316. cftbsub(n, a, ip, nw, w);
  317. }
  318. }
  319. }
  320. /* -------- initializing routines -------- */
  321. #include <math.h>
  322. void makewt(int nw, int *ip, double *w)
  323. {
  324. void makeipt(int nw, int *ip);
  325. int j, nwh, nw0, nw1;
  326. double delta, wn4r, wk1r, wk1i, wk3r, wk3i;
  327. ip[0] = nw;
  328. ip[1] = 1;
  329. if (nw > 2) {
  330. nwh = nw >> 1;
  331. delta = atan(1.0) / nwh;
  332. wn4r = cos(delta * nwh);
  333. w[0] = 1;
  334. w[1] = wn4r;
  335. if (nwh == 4) {
  336. w[2] = cos(delta * 2);
  337. w[3] = sin(delta * 2);
  338. } else if (nwh > 4) {
  339. makeipt(nw, ip);
  340. w[2] = 0.5 / cos(delta * 2);
  341. w[3] = 0.5 / cos(delta * 6);
  342. for (j = 4; j < nwh; j += 4) {
  343. w[j] = cos(delta * j);
  344. w[j + 1] = sin(delta * j);
  345. w[j + 2] = cos(3 * delta * j);
  346. w[j + 3] = -sin(3 * delta * j);
  347. }
  348. }
  349. nw0 = 0;
  350. while (nwh > 2) {
  351. nw1 = nw0 + nwh;
  352. nwh >>= 1;
  353. w[nw1] = 1;
  354. w[nw1 + 1] = wn4r;
  355. if (nwh == 4) {
  356. wk1r = w[nw0 + 4];
  357. wk1i = w[nw0 + 5];
  358. w[nw1 + 2] = wk1r;
  359. w[nw1 + 3] = wk1i;
  360. } else if (nwh > 4) {
  361. wk1r = w[nw0 + 4];
  362. wk3r = w[nw0 + 6];
  363. w[nw1 + 2] = 0.5 / wk1r;
  364. w[nw1 + 3] = 0.5 / wk3r;
  365. for (j = 4; j < nwh; j += 4) {
  366. wk1r = w[nw0 + 2 * j];
  367. wk1i = w[nw0 + 2 * j + 1];
  368. wk3r = w[nw0 + 2 * j + 2];
  369. wk3i = w[nw0 + 2 * j + 3];
  370. w[nw1 + j] = wk1r;
  371. w[nw1 + j + 1] = wk1i;
  372. w[nw1 + j + 2] = wk3r;
  373. w[nw1 + j + 3] = wk3i;
  374. }
  375. }
  376. nw0 = nw1;
  377. }
  378. }
  379. }
  380. void makeipt(int nw, int *ip)
  381. {
  382. int j, l, m, m2, p, q;
  383. ip[2] = 0;
  384. ip[3] = 16;
  385. m = 2;
  386. for (l = nw; l > 32; l >>= 2) {
  387. m2 = m << 1;
  388. q = m2 << 3;
  389. for (j = m; j < m2; j++) {
  390. p = ip[j] << 2;
  391. ip[m + j] = p;
  392. ip[m2 + j] = p + q;
  393. }
  394. m = m2;
  395. }
  396. }
  397. void makect(int nc, int *ip, double *c)
  398. {
  399. int j, nch;
  400. double delta;
  401. ip[1] = nc;
  402. if (nc > 1) {
  403. nch = nc >> 1;
  404. delta = atan(1.0) / nch;
  405. c[0] = cos(delta * nch);
  406. c[nch] = 0.5 * c[0];
  407. for (j = 1; j < nch; j++) {
  408. c[j] = 0.5 * cos(delta * j);
  409. c[nc - j] = 0.5 * sin(delta * j);
  410. }
  411. }
  412. }
  413. /* -------- child routines -------- */
  414. #ifdef USE_CDFT_PTHREADS
  415. #define USE_CDFT_THREADS
  416. #ifndef CDFT_THREADS_BEGIN_N
  417. #define CDFT_THREADS_BEGIN_N 8192
  418. #endif
  419. #ifndef CDFT_4THREADS_BEGIN_N
  420. #define CDFT_4THREADS_BEGIN_N 65536
  421. #endif
  422. #include <pthread.h>
  423. #include <stdio.h>
  424. #include <stdlib.h>
  425. #define cdft_thread_t pthread_t
  426. #define cdft_thread_create(thp,func,argp) { \
  427. if (pthread_create(thp, NULL, func, (void *) argp) != 0) { \
  428. fprintf(stderr, "cdft thread error\n"); \
  429. exit(1); \
  430. } \
  431. }
  432. #define cdft_thread_wait(th) { \
  433. if (pthread_join(th, NULL) != 0) { \
  434. fprintf(stderr, "cdft thread error\n"); \
  435. exit(1); \
  436. } \
  437. }
  438. #endif /* USE_CDFT_PTHREADS */
  439. #ifdef USE_CDFT_WINTHREADS
  440. #define USE_CDFT_THREADS
  441. #ifndef CDFT_THREADS_BEGIN_N
  442. #define CDFT_THREADS_BEGIN_N 32768
  443. #endif
  444. #ifndef CDFT_4THREADS_BEGIN_N
  445. #define CDFT_4THREADS_BEGIN_N 524288
  446. #endif
  447. #include <windows.h>
  448. #include <stdio.h>
  449. #include <stdlib.h>
  450. #define cdft_thread_t HANDLE
  451. #define cdft_thread_create(thp,func,argp) { \
  452. DWORD thid; \
  453. *(thp) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) func, (LPVOID) argp, 0, &thid); \
  454. if (*(thp) == 0) { \
  455. fprintf(stderr, "cdft thread error\n"); \
  456. exit(1); \
  457. } \
  458. }
  459. #define cdft_thread_wait(th) { \
  460. WaitForSingleObject(th, INFINITE); \
  461. CloseHandle(th); \
  462. }
  463. #endif /* USE_CDFT_WINTHREADS */
  464. void cftfsub(int n, double *a, int *ip, int nw, double *w)
  465. {
  466. void bitrv2(int n, int *ip, double *a);
  467. void bitrv216(double *a);
  468. void bitrv208(double *a);
  469. void cftf1st(int n, double *a, double *w);
  470. void cftrec4(int n, double *a, int nw, double *w);
  471. void cftleaf(int n, int isplt, double *a, int nw, double *w);
  472. void cftfx41(int n, double *a, int nw, double *w);
  473. void cftf161(double *a, double *w);
  474. void cftf081(double *a, double *w);
  475. void cftf040(double *a);
  476. void cftx020(double *a);
  477. #ifdef USE_CDFT_THREADS
  478. void cftrec4_th(int n, double *a, int nw, double *w);
  479. #endif /* USE_CDFT_THREADS */
  480. if (n > 8) {
  481. if (n > 32) {
  482. cftf1st(n, a, &w[nw - (n >> 2)]);
  483. #ifdef USE_CDFT_THREADS
  484. if (n > CDFT_THREADS_BEGIN_N) {
  485. cftrec4_th(n, a, nw, w);
  486. } else
  487. #endif /* USE_CDFT_THREADS */
  488. if (n > 512) {
  489. cftrec4(n, a, nw, w);
  490. } else if (n > 128) {
  491. cftleaf(n, 1, a, nw, w);
  492. } else {
  493. cftfx41(n, a, nw, w);
  494. }
  495. bitrv2(n, ip, a);
  496. } else if (n == 32) {
  497. cftf161(a, &w[nw - 8]);
  498. bitrv216(a);
  499. } else {
  500. cftf081(a, w);
  501. bitrv208(a);
  502. }
  503. } else if (n == 8) {
  504. cftf040(a);
  505. } else if (n == 4) {
  506. cftx020(a);
  507. }
  508. }
  509. void cftbsub(int n, double *a, int *ip, int nw, double *w)
  510. {
  511. void bitrv2conj(int n, int *ip, double *a);
  512. void bitrv216neg(double *a);
  513. void bitrv208neg(double *a);
  514. void cftb1st(int n, double *a, double *w);
  515. void cftrec4(int n, double *a, int nw, double *w);
  516. void cftleaf(int n, int isplt, double *a, int nw, double *w);
  517. void cftfx41(int n, double *a, int nw, double *w);
  518. void cftf161(double *a, double *w);
  519. void cftf081(double *a, double *w);
  520. void cftb040(double *a);
  521. void cftx020(double *a);
  522. #ifdef USE_CDFT_THREADS
  523. void cftrec4_th(int n, double *a, int nw, double *w);
  524. #endif /* USE_CDFT_THREADS */
  525. if (n > 8) {
  526. if (n > 32) {
  527. cftb1st(n, a, &w[nw - (n >> 2)]);
  528. #ifdef USE_CDFT_THREADS
  529. if (n > CDFT_THREADS_BEGIN_N) {
  530. cftrec4_th(n, a, nw, w);
  531. } else
  532. #endif /* USE_CDFT_THREADS */
  533. if (n > 512) {
  534. cftrec4(n, a, nw, w);
  535. } else if (n > 128) {
  536. cftleaf(n, 1, a, nw, w);
  537. } else {
  538. cftfx41(n, a, nw, w);
  539. }
  540. bitrv2conj(n, ip, a);
  541. } else if (n == 32) {
  542. cftf161(a, &w[nw - 8]);
  543. bitrv216neg(a);
  544. } else {
  545. cftf081(a, w);
  546. bitrv208neg(a);
  547. }
  548. } else if (n == 8) {
  549. cftb040(a);
  550. } else if (n == 4) {
  551. cftx020(a);
  552. }
  553. }
  554. void bitrv2(int n, int *ip, double *a)
  555. {
  556. int j, j1, k, k1, l, m, nh, nm;
  557. double xr, xi, yr, yi;
  558. m = 1;
  559. for (l = n >> 2; l > 8; l >>= 2) {
  560. m <<= 1;
  561. }
  562. nh = n >> 1;
  563. nm = 4 * m;
  564. if (l == 8) {
  565. for (k = 0; k < m; k++) {
  566. for (j = 0; j < k; j++) {
  567. j1 = 4 * j + 2 * ip[m + k];
  568. k1 = 4 * k + 2 * ip[m + j];
  569. xr = a[j1];
  570. xi = a[j1 + 1];
  571. yr = a[k1];
  572. yi = a[k1 + 1];
  573. a[j1] = yr;
  574. a[j1 + 1] = yi;
  575. a[k1] = xr;
  576. a[k1 + 1] = xi;
  577. j1 += nm;
  578. k1 += 2 * nm;
  579. xr = a[j1];
  580. xi = a[j1 + 1];
  581. yr = a[k1];
  582. yi = a[k1 + 1];
  583. a[j1] = yr;
  584. a[j1 + 1] = yi;
  585. a[k1] = xr;
  586. a[k1 + 1] = xi;
  587. j1 += nm;
  588. k1 -= nm;
  589. xr = a[j1];
  590. xi = a[j1 + 1];
  591. yr = a[k1];
  592. yi = a[k1 + 1];
  593. a[j1] = yr;
  594. a[j1 + 1] = yi;
  595. a[k1] = xr;
  596. a[k1 + 1] = xi;
  597. j1 += nm;
  598. k1 += 2 * nm;
  599. xr = a[j1];
  600. xi = a[j1 + 1];
  601. yr = a[k1];
  602. yi = a[k1 + 1];
  603. a[j1] = yr;
  604. a[j1 + 1] = yi;
  605. a[k1] = xr;
  606. a[k1 + 1] = xi;
  607. j1 += nh;
  608. k1 += 2;
  609. xr = a[j1];
  610. xi = a[j1 + 1];
  611. yr = a[k1];
  612. yi = a[k1 + 1];
  613. a[j1] = yr;
  614. a[j1 + 1] = yi;
  615. a[k1] = xr;
  616. a[k1 + 1] = xi;
  617. j1 -= nm;
  618. k1 -= 2 * nm;
  619. xr = a[j1];
  620. xi = a[j1 + 1];
  621. yr = a[k1];
  622. yi = a[k1 + 1];
  623. a[j1] = yr;
  624. a[j1 + 1] = yi;
  625. a[k1] = xr;
  626. a[k1 + 1] = xi;
  627. j1 -= nm;
  628. k1 += nm;
  629. xr = a[j1];
  630. xi = a[j1 + 1];
  631. yr = a[k1];
  632. yi = a[k1 + 1];
  633. a[j1] = yr;
  634. a[j1 + 1] = yi;
  635. a[k1] = xr;
  636. a[k1 + 1] = xi;
  637. j1 -= nm;
  638. k1 -= 2 * nm;
  639. xr = a[j1];
  640. xi = a[j1 + 1];
  641. yr = a[k1];
  642. yi = a[k1 + 1];
  643. a[j1] = yr;
  644. a[j1 + 1] = yi;
  645. a[k1] = xr;
  646. a[k1 + 1] = xi;
  647. j1 += 2;
  648. k1 += nh;
  649. xr = a[j1];
  650. xi = a[j1 + 1];
  651. yr = a[k1];
  652. yi = a[k1 + 1];
  653. a[j1] = yr;
  654. a[j1 + 1] = yi;
  655. a[k1] = xr;
  656. a[k1 + 1] = xi;
  657. j1 += nm;
  658. k1 += 2 * nm;
  659. xr = a[j1];
  660. xi = a[j1 + 1];
  661. yr = a[k1];
  662. yi = a[k1 + 1];
  663. a[j1] = yr;
  664. a[j1 + 1] = yi;
  665. a[k1] = xr;
  666. a[k1 + 1] = xi;
  667. j1 += nm;
  668. k1 -= nm;
  669. xr = a[j1];
  670. xi = a[j1 + 1];
  671. yr = a[k1];
  672. yi = a[k1 + 1];
  673. a[j1] = yr;
  674. a[j1 + 1] = yi;
  675. a[k1] = xr;
  676. a[k1 + 1] = xi;
  677. j1 += nm;
  678. k1 += 2 * nm;
  679. xr = a[j1];
  680. xi = a[j1 + 1];
  681. yr = a[k1];
  682. yi = a[k1 + 1];
  683. a[j1] = yr;
  684. a[j1 + 1] = yi;
  685. a[k1] = xr;
  686. a[k1 + 1] = xi;
  687. j1 -= nh;
  688. k1 -= 2;
  689. xr = a[j1];
  690. xi = a[j1 + 1];
  691. yr = a[k1];
  692. yi = a[k1 + 1];
  693. a[j1] = yr;
  694. a[j1 + 1] = yi;
  695. a[k1] = xr;
  696. a[k1 + 1] = xi;
  697. j1 -= nm;
  698. k1 -= 2 * nm;
  699. xr = a[j1];
  700. xi = a[j1 + 1];
  701. yr = a[k1];
  702. yi = a[k1 + 1];
  703. a[j1] = yr;
  704. a[j1 + 1] = yi;
  705. a[k1] = xr;
  706. a[k1 + 1] = xi;
  707. j1 -= nm;
  708. k1 += nm;
  709. xr = a[j1];
  710. xi = a[j1 + 1];
  711. yr = a[k1];
  712. yi = a[k1 + 1];
  713. a[j1] = yr;
  714. a[j1 + 1] = yi;
  715. a[k1] = xr;
  716. a[k1 + 1] = xi;
  717. j1 -= nm;
  718. k1 -= 2 * nm;
  719. xr = a[j1];
  720. xi = a[j1 + 1];
  721. yr = a[k1];
  722. yi = a[k1 + 1];
  723. a[j1] = yr;
  724. a[j1 + 1] = yi;
  725. a[k1] = xr;
  726. a[k1 + 1] = xi;
  727. }
  728. k1 = 4 * k + 2 * ip[m + k];
  729. j1 = k1 + 2;
  730. k1 += nh;
  731. xr = a[j1];
  732. xi = a[j1 + 1];
  733. yr = a[k1];
  734. yi = a[k1 + 1];
  735. a[j1] = yr;
  736. a[j1 + 1] = yi;
  737. a[k1] = xr;
  738. a[k1 + 1] = xi;
  739. j1 += nm;
  740. k1 += 2 * nm;
  741. xr = a[j1];
  742. xi = a[j1 + 1];
  743. yr = a[k1];
  744. yi = a[k1 + 1];
  745. a[j1] = yr;
  746. a[j1 + 1] = yi;
  747. a[k1] = xr;
  748. a[k1 + 1] = xi;
  749. j1 += nm;
  750. k1 -= nm;
  751. xr = a[j1];
  752. xi = a[j1 + 1];
  753. yr = a[k1];
  754. yi = a[k1 + 1];
  755. a[j1] = yr;
  756. a[j1 + 1] = yi;
  757. a[k1] = xr;
  758. a[k1 + 1] = xi;
  759. j1 -= 2;
  760. k1 -= nh;
  761. xr = a[j1];
  762. xi = a[j1 + 1];
  763. yr = a[k1];
  764. yi = a[k1 + 1];
  765. a[j1] = yr;
  766. a[j1 + 1] = yi;
  767. a[k1] = xr;
  768. a[k1 + 1] = xi;
  769. j1 += nh + 2;
  770. k1 += nh + 2;
  771. xr = a[j1];
  772. xi = a[j1 + 1];
  773. yr = a[k1];
  774. yi = a[k1 + 1];
  775. a[j1] = yr;
  776. a[j1 + 1] = yi;
  777. a[k1] = xr;
  778. a[k1 + 1] = xi;
  779. j1 -= nh - nm;
  780. k1 += 2 * nm - 2;
  781. xr = a[j1];
  782. xi = a[j1 + 1];
  783. yr = a[k1];
  784. yi = a[k1 + 1];
  785. a[j1] = yr;
  786. a[j1 + 1] = yi;
  787. a[k1] = xr;
  788. a[k1 + 1] = xi;
  789. }
  790. } else {
  791. for (k = 0; k < m; k++) {
  792. for (j = 0; j < k; j++) {
  793. j1 = 4 * j + ip[m + k];
  794. k1 = 4 * k + ip[m + j];
  795. xr = a[j1];
  796. xi = a[j1 + 1];
  797. yr = a[k1];
  798. yi = a[k1 + 1];
  799. a[j1] = yr;
  800. a[j1 + 1] = yi;
  801. a[k1] = xr;
  802. a[k1 + 1] = xi;
  803. j1 += nm;
  804. k1 += nm;
  805. xr = a[j1];
  806. xi = a[j1 + 1];
  807. yr = a[k1];
  808. yi = a[k1 + 1];
  809. a[j1] = yr;
  810. a[j1 + 1] = yi;
  811. a[k1] = xr;
  812. a[k1 + 1] = xi;
  813. j1 += nh;
  814. k1 += 2;
  815. xr = a[j1];
  816. xi = a[j1 + 1];
  817. yr = a[k1];
  818. yi = a[k1 + 1];
  819. a[j1] = yr;
  820. a[j1 + 1] = yi;
  821. a[k1] = xr;
  822. a[k1 + 1] = xi;
  823. j1 -= nm;
  824. k1 -= nm;
  825. xr = a[j1];
  826. xi = a[j1 + 1];
  827. yr = a[k1];
  828. yi = a[k1 + 1];
  829. a[j1] = yr;
  830. a[j1 + 1] = yi;
  831. a[k1] = xr;
  832. a[k1 + 1] = xi;
  833. j1 += 2;
  834. k1 += nh;
  835. xr = a[j1];
  836. xi = a[j1 + 1];
  837. yr = a[k1];
  838. yi = a[k1 + 1];
  839. a[j1] = yr;
  840. a[j1 + 1] = yi;
  841. a[k1] = xr;
  842. a[k1 + 1] = xi;
  843. j1 += nm;
  844. k1 += nm;
  845. xr = a[j1];
  846. xi = a[j1 + 1];
  847. yr = a[k1];
  848. yi = a[k1 + 1];
  849. a[j1] = yr;
  850. a[j1 + 1] = yi;
  851. a[k1] = xr;
  852. a[k1 + 1] = xi;
  853. j1 -= nh;
  854. k1 -= 2;
  855. xr = a[j1];
  856. xi = a[j1 + 1];
  857. yr = a[k1];
  858. yi = a[k1 + 1];
  859. a[j1] = yr;
  860. a[j1 + 1] = yi;
  861. a[k1] = xr;
  862. a[k1 + 1] = xi;
  863. j1 -= nm;
  864. k1 -= nm;
  865. xr = a[j1];
  866. xi = a[j1 + 1];
  867. yr = a[k1];
  868. yi = a[k1 + 1];
  869. a[j1] = yr;
  870. a[j1 + 1] = yi;
  871. a[k1] = xr;
  872. a[k1 + 1] = xi;
  873. }
  874. k1 = 4 * k + ip[m + k];
  875. j1 = k1 + 2;
  876. k1 += nh;
  877. xr = a[j1];
  878. xi = a[j1 + 1];
  879. yr = a[k1];
  880. yi = a[k1 + 1];
  881. a[j1] = yr;
  882. a[j1 + 1] = yi;
  883. a[k1] = xr;
  884. a[k1 + 1] = xi;
  885. j1 += nm;
  886. k1 += nm;
  887. xr = a[j1];
  888. xi = a[j1 + 1];
  889. yr = a[k1];
  890. yi = a[k1 + 1];
  891. a[j1] = yr;
  892. a[j1 + 1] = yi;
  893. a[k1] = xr;
  894. a[k1 + 1] = xi;
  895. }
  896. }
  897. }
  898. void bitrv2conj(int n, int *ip, double *a)
  899. {
  900. int j, j1, k, k1, l, m, nh, nm;
  901. double xr, xi, yr, yi;
  902. m = 1;
  903. for (l = n >> 2; l > 8; l >>= 2) {
  904. m <<= 1;
  905. }
  906. nh = n >> 1;
  907. nm = 4 * m;
  908. if (l == 8) {
  909. for (k = 0; k < m; k++) {
  910. for (j = 0; j < k; j++) {
  911. j1 = 4 * j + 2 * ip[m + k];
  912. k1 = 4 * k + 2 * ip[m + j];
  913. xr = a[j1];
  914. xi = -a[j1 + 1];
  915. yr = a[k1];
  916. yi = -a[k1 + 1];
  917. a[j1] = yr;
  918. a[j1 + 1] = yi;
  919. a[k1] = xr;
  920. a[k1 + 1] = xi;
  921. j1 += nm;
  922. k1 += 2 * nm;
  923. xr = a[j1];
  924. xi = -a[j1 + 1];
  925. yr = a[k1];
  926. yi = -a[k1 + 1];
  927. a[j1] = yr;
  928. a[j1 + 1] = yi;
  929. a[k1] = xr;
  930. a[k1 + 1] = xi;
  931. j1 += nm;
  932. k1 -= nm;
  933. xr = a[j1];
  934. xi = -a[j1 + 1];
  935. yr = a[k1];
  936. yi = -a[k1 + 1];
  937. a[j1] = yr;
  938. a[j1 + 1] = yi;
  939. a[k1] = xr;
  940. a[k1 + 1] = xi;
  941. j1 += nm;
  942. k1 += 2 * nm;
  943. xr = a[j1];
  944. xi = -a[j1 + 1];
  945. yr = a[k1];
  946. yi = -a[k1 + 1];
  947. a[j1] = yr;
  948. a[j1 + 1] = yi;
  949. a[k1] = xr;
  950. a[k1 + 1] = xi;
  951. j1 += nh;
  952. k1 += 2;
  953. xr = a[j1];
  954. xi = -a[j1 + 1];
  955. yr = a[k1];
  956. yi = -a[k1 + 1];
  957. a[j1] = yr;
  958. a[j1 + 1] = yi;
  959. a[k1] = xr;
  960. a[k1 + 1] = xi;
  961. j1 -= nm;
  962. k1 -= 2 * nm;
  963. xr = a[j1];
  964. xi = -a[j1 + 1];
  965. yr = a[k1];
  966. yi = -a[k1 + 1];
  967. a[j1] = yr;
  968. a[j1 + 1] = yi;
  969. a[k1] = xr;
  970. a[k1 + 1] = xi;
  971. j1 -= nm;
  972. k1 += nm;
  973. xr = a[j1];
  974. xi = -a[j1 + 1];
  975. yr = a[k1];
  976. yi = -a[k1 + 1];
  977. a[j1] = yr;
  978. a[j1 + 1] = yi;
  979. a[k1] = xr;
  980. a[k1 + 1] = xi;
  981. j1 -= nm;
  982. k1 -= 2 * nm;
  983. xr = a[j1];
  984. xi = -a[j1 + 1];
  985. yr = a[k1];
  986. yi = -a[k1 + 1];
  987. a[j1] = yr;
  988. a[j1 + 1] = yi;
  989. a[k1] = xr;
  990. a[k1 + 1] = xi;
  991. j1 += 2;
  992. k1 += nh;
  993. xr = a[j1];
  994. xi = -a[j1 + 1];
  995. yr = a[k1];
  996. yi = -a[k1 + 1];
  997. a[j1] = yr;
  998. a[j1 + 1] = yi;
  999. a[k1] = xr;
  1000. a[k1 + 1] = xi;
  1001. j1 += nm;
  1002. k1 += 2 * nm;
  1003. xr = a[j1];
  1004. xi = -a[j1 + 1];
  1005. yr = a[k1];
  1006. yi = -a[k1 + 1];
  1007. a[j1] = yr;
  1008. a[j1 + 1] = yi;
  1009. a[k1] = xr;
  1010. a[k1 + 1] = xi;
  1011. j1 += nm;
  1012. k1 -= nm;
  1013. xr = a[j1];
  1014. xi = -a[j1 + 1];
  1015. yr = a[k1];
  1016. yi = -a[k1 + 1];
  1017. a[j1] = yr;
  1018. a[j1 + 1] = yi;
  1019. a[k1] = xr;
  1020. a[k1 + 1] = xi;
  1021. j1 += nm;
  1022. k1 += 2 * nm;
  1023. xr = a[j1];
  1024. xi = -a[j1 + 1];
  1025. yr = a[k1];
  1026. yi = -a[k1 + 1];
  1027. a[j1] = yr;
  1028. a[j1 + 1] = yi;
  1029. a[k1] = xr;
  1030. a[k1 + 1] = xi;
  1031. j1 -= nh;
  1032. k1 -= 2;
  1033. xr = a[j1];
  1034. xi = -a[j1 + 1];
  1035. yr = a[k1];
  1036. yi = -a[k1 + 1];
  1037. a[j1] = yr;
  1038. a[j1 + 1] = yi;
  1039. a[k1] = xr;
  1040. a[k1 + 1] = xi;
  1041. j1 -= nm;
  1042. k1 -= 2 * nm;
  1043. xr = a[j1];
  1044. xi = -a[j1 + 1];
  1045. yr = a[k1];
  1046. yi = -a[k1 + 1];
  1047. a[j1] = yr;
  1048. a[j1 + 1] = yi;
  1049. a[k1] = xr;
  1050. a[k1 + 1] = xi;
  1051. j1 -= nm;
  1052. k1 += nm;
  1053. xr = a[j1];
  1054. xi = -a[j1 + 1];
  1055. yr = a[k1];
  1056. yi = -a[k1 + 1];
  1057. a[j1] = yr;
  1058. a[j1 + 1] = yi;
  1059. a[k1] = xr;
  1060. a[k1 + 1] = xi;
  1061. j1 -= nm;
  1062. k1 -= 2 * nm;
  1063. xr = a[j1];
  1064. xi = -a[j1 + 1];
  1065. yr = a[k1];
  1066. yi = -a[k1 + 1];
  1067. a[j1] = yr;
  1068. a[j1 + 1] = yi;
  1069. a[k1] = xr;
  1070. a[k1 + 1] = xi;
  1071. }
  1072. k1 = 4 * k + 2 * ip[m + k];
  1073. j1 = k1 + 2;
  1074. k1 += nh;
  1075. a[j1 - 1] = -a[j1 - 1];
  1076. xr = a[j1];
  1077. xi = -a[j1 + 1];
  1078. yr = a[k1];
  1079. yi = -a[k1 + 1];
  1080. a[j1] = yr;
  1081. a[j1 + 1] = yi;
  1082. a[k1] = xr;
  1083. a[k1 + 1] = xi;
  1084. a[k1 + 3] = -a[k1 + 3];
  1085. j1 += nm;
  1086. k1 += 2 * nm;
  1087. xr = a[j1];
  1088. xi = -a[j1 + 1];
  1089. yr = a[k1];
  1090. yi = -a[k1 + 1];
  1091. a[j1] = yr;
  1092. a[j1 + 1] = yi;
  1093. a[k1] = xr;
  1094. a[k1 + 1] = xi;
  1095. j1 += nm;
  1096. k1 -= nm;
  1097. xr = a[j1];
  1098. xi = -a[j1 + 1];
  1099. yr = a[k1];
  1100. yi = -a[k1 + 1];
  1101. a[j1] = yr;
  1102. a[j1 + 1] = yi;
  1103. a[k1] = xr;
  1104. a[k1 + 1] = xi;
  1105. j1 -= 2;
  1106. k1 -= nh;
  1107. xr = a[j1];
  1108. xi = -a[j1 + 1];
  1109. yr = a[k1];
  1110. yi = -a[k1 + 1];
  1111. a[j1] = yr;
  1112. a[j1 + 1] = yi;
  1113. a[k1] = xr;
  1114. a[k1 + 1] = xi;
  1115. j1 += nh + 2;
  1116. k1 += nh + 2;
  1117. xr = a[j1];
  1118. xi = -a[j1 + 1];
  1119. yr = a[k1];
  1120. yi = -a[k1 + 1];
  1121. a[j1] = yr;
  1122. a[j1 + 1] = yi;
  1123. a[k1] = xr;
  1124. a[k1 + 1] = xi;
  1125. j1 -= nh - nm;
  1126. k1 += 2 * nm - 2;
  1127. a[j1 - 1] = -a[j1 - 1];
  1128. xr = a[j1];
  1129. xi = -a[j1 + 1];
  1130. yr = a[k1];
  1131. yi = -a[k1 + 1];
  1132. a[j1] = yr;
  1133. a[j1 + 1] = yi;
  1134. a[k1] = xr;
  1135. a[k1 + 1] = xi;
  1136. a[k1 + 3] = -a[k1 + 3];
  1137. }
  1138. } else {
  1139. for (k = 0; k < m; k++) {
  1140. for (j = 0; j < k; j++) {
  1141. j1 = 4 * j + ip[m + k];
  1142. k1 = 4 * k + ip[m + j];
  1143. xr = a[j1];
  1144. xi = -a[j1 + 1];
  1145. yr = a[k1];
  1146. yi = -a[k1 + 1];
  1147. a[j1] = yr;
  1148. a[j1 + 1] = yi;
  1149. a[k1] = xr;
  1150. a[k1 + 1] = xi;
  1151. j1 += nm;
  1152. k1 += nm;
  1153. xr = a[j1];
  1154. xi = -a[j1 + 1];
  1155. yr = a[k1];
  1156. yi = -a[k1 + 1];
  1157. a[j1] = yr;
  1158. a[j1 + 1] = yi;
  1159. a[k1] = xr;
  1160. a[k1 + 1] = xi;
  1161. j1 += nh;
  1162. k1 += 2;
  1163. xr = a[j1];
  1164. xi = -a[j1 + 1];
  1165. yr = a[k1];
  1166. yi = -a[k1 + 1];
  1167. a[j1] = yr;
  1168. a[j1 + 1] = yi;
  1169. a[k1] = xr;
  1170. a[k1 + 1] = xi;
  1171. j1 -= nm;
  1172. k1 -= nm;
  1173. xr = a[j1];
  1174. xi = -a[j1 + 1];
  1175. yr = a[k1];
  1176. yi = -a[k1 + 1];
  1177. a[j1] = yr;
  1178. a[j1 + 1] = yi;
  1179. a[k1] = xr;
  1180. a[k1 + 1] = xi;
  1181. j1 += 2;
  1182. k1 += nh;
  1183. xr = a[j1];
  1184. xi = -a[j1 + 1];
  1185. yr = a[k1];
  1186. yi = -a[k1 + 1];
  1187. a[j1] = yr;
  1188. a[j1 + 1] = yi;
  1189. a[k1] = xr;
  1190. a[k1 + 1] = xi;
  1191. j1 += nm;
  1192. k1 += nm;
  1193. xr = a[j1];
  1194. xi = -a[j1 + 1];
  1195. yr = a[k1];
  1196. yi = -a[k1 + 1];
  1197. a[j1] = yr;
  1198. a[j1 + 1] = yi;
  1199. a[k1] = xr;
  1200. a[k1 + 1] = xi;
  1201. j1 -= nh;
  1202. k1 -= 2;
  1203. xr = a[j1];
  1204. xi = -a[j1 + 1];
  1205. yr = a[k1];
  1206. yi = -a[k1 + 1];
  1207. a[j1] = yr;
  1208. a[j1 + 1] = yi;
  1209. a[k1] = xr;
  1210. a[k1 + 1] = xi;
  1211. j1 -= nm;
  1212. k1 -= nm;
  1213. xr = a[j1];
  1214. xi = -a[j1 + 1];
  1215. yr = a[k1];
  1216. yi = -a[k1 + 1];
  1217. a[j1] = yr;
  1218. a[j1 + 1] = yi;
  1219. a[k1] = xr;
  1220. a[k1 + 1] = xi;
  1221. }
  1222. k1 = 4 * k + ip[m + k];
  1223. j1 = k1 + 2;
  1224. k1 += nh;
  1225. a[j1 - 1] = -a[j1 - 1];
  1226. xr = a[j1];
  1227. xi = -a[j1 + 1];
  1228. yr = a[k1];
  1229. yi = -a[k1 + 1];
  1230. a[j1] = yr;
  1231. a[j1 + 1] = yi;
  1232. a[k1] = xr;
  1233. a[k1 + 1] = xi;
  1234. a[k1 + 3] = -a[k1 + 3];
  1235. j1 += nm;
  1236. k1 += nm;
  1237. a[j1 - 1] = -a[j1 - 1];
  1238. xr = a[j1];
  1239. xi = -a[j1 + 1];
  1240. yr = a[k1];
  1241. yi = -a[k1 + 1];
  1242. a[j1] = yr;
  1243. a[j1 + 1] = yi;
  1244. a[k1] = xr;
  1245. a[k1 + 1] = xi;
  1246. a[k1 + 3] = -a[k1 + 3];
  1247. }
  1248. }
  1249. }
  1250. void bitrv216(double *a)
  1251. {
  1252. double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i,
  1253. x5r, x5i, x7r, x7i, x8r, x8i, x10r, x10i,
  1254. x11r, x11i, x12r, x12i, x13r, x13i, x14r, x14i;
  1255. x1r = a[2];
  1256. x1i = a[3];
  1257. x2r = a[4];
  1258. x2i = a[5];
  1259. x3r = a[6];
  1260. x3i = a[7];
  1261. x4r = a[8];
  1262. x4i = a[9];
  1263. x5r = a[10];
  1264. x5i = a[11];
  1265. x7r = a[14];
  1266. x7i = a[15];
  1267. x8r = a[16];
  1268. x8i = a[17];
  1269. x10r = a[20];
  1270. x10i = a[21];
  1271. x11r = a[22];
  1272. x11i = a[23];
  1273. x12r = a[24];
  1274. x12i = a[25];
  1275. x13r = a[26];
  1276. x13i = a[27];
  1277. x14r = a[28];
  1278. x14i = a[29];
  1279. a[2] = x8r;
  1280. a[3] = x8i;
  1281. a[4] = x4r;
  1282. a[5] = x4i;
  1283. a[6] = x12r;
  1284. a[7] = x12i;
  1285. a[8] = x2r;
  1286. a[9] = x2i;
  1287. a[10] = x10r;
  1288. a[11] = x10i;
  1289. a[14] = x14r;
  1290. a[15] = x14i;
  1291. a[16] = x1r;
  1292. a[17] = x1i;
  1293. a[20] = x5r;
  1294. a[21] = x5i;
  1295. a[22] = x13r;
  1296. a[23] = x13i;
  1297. a[24] = x3r;
  1298. a[25] = x3i;
  1299. a[26] = x11r;
  1300. a[27] = x11i;
  1301. a[28] = x7r;
  1302. a[29] = x7i;
  1303. }
  1304. void bitrv216neg(double *a)
  1305. {
  1306. double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i,
  1307. x5r, x5i, x6r, x6i, x7r, x7i, x8r, x8i,
  1308. x9r, x9i, x10r, x10i, x11r, x11i, x12r, x12i,
  1309. x13r, x13i, x14r, x14i, x15r, x15i;
  1310. x1r = a[2];
  1311. x1i = a[3];
  1312. x2r = a[4];
  1313. x2i = a[5];
  1314. x3r = a[6];
  1315. x3i = a[7];
  1316. x4r = a[8];
  1317. x4i = a[9];
  1318. x5r = a[10];
  1319. x5i = a[11];
  1320. x6r = a[12];
  1321. x6i = a[13];
  1322. x7r = a[14];
  1323. x7i = a[15];
  1324. x8r = a[16];
  1325. x8i = a[17];
  1326. x9r = a[18];
  1327. x9i = a[19];
  1328. x10r = a[20];
  1329. x10i = a[21];
  1330. x11r = a[22];
  1331. x11i = a[23];
  1332. x12r = a[24];
  1333. x12i = a[25];
  1334. x13r = a[26];
  1335. x13i = a[27];
  1336. x14r = a[28];
  1337. x14i = a[29];
  1338. x15r = a[30];
  1339. x15i = a[31];
  1340. a[2] = x15r;
  1341. a[3] = x15i;
  1342. a[4] = x7r;
  1343. a[5] = x7i;
  1344. a[6] = x11r;
  1345. a[7] = x11i;
  1346. a[8] = x3r;
  1347. a[9] = x3i;
  1348. a[10] = x13r;
  1349. a[11] = x13i;
  1350. a[12] = x5r;
  1351. a[13] = x5i;
  1352. a[14] = x9r;
  1353. a[15] = x9i;
  1354. a[16] = x1r;
  1355. a[17] = x1i;
  1356. a[18] = x14r;
  1357. a[19] = x14i;
  1358. a[20] = x6r;
  1359. a[21] = x6i;
  1360. a[22] = x10r;
  1361. a[23] = x10i;
  1362. a[24] = x2r;
  1363. a[25] = x2i;
  1364. a[26] = x12r;
  1365. a[27] = x12i;
  1366. a[28] = x4r;
  1367. a[29] = x4i;
  1368. a[30] = x8r;
  1369. a[31] = x8i;
  1370. }
  1371. void bitrv208(double *a)
  1372. {
  1373. double x1r, x1i, x3r, x3i, x4r, x4i, x6r, x6i;
  1374. x1r = a[2];
  1375. x1i = a[3];
  1376. x3r = a[6];
  1377. x3i = a[7];
  1378. x4r = a[8];
  1379. x4i = a[9];
  1380. x6r = a[12];
  1381. x6i = a[13];
  1382. a[2] = x4r;
  1383. a[3] = x4i;
  1384. a[6] = x6r;
  1385. a[7] = x6i;
  1386. a[8] = x1r;
  1387. a[9] = x1i;
  1388. a[12] = x3r;
  1389. a[13] = x3i;
  1390. }
  1391. void bitrv208neg(double *a)
  1392. {
  1393. double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i,
  1394. x5r, x5i, x6r, x6i, x7r, x7i;
  1395. x1r = a[2];
  1396. x1i = a[3];
  1397. x2r = a[4];
  1398. x2i = a[5];
  1399. x3r = a[6];
  1400. x3i = a[7];
  1401. x4r = a[8];
  1402. x4i = a[9];
  1403. x5r = a[10];
  1404. x5i = a[11];
  1405. x6r = a[12];
  1406. x6i = a[13];
  1407. x7r = a[14];
  1408. x7i = a[15];
  1409. a[2] = x7r;
  1410. a[3] = x7i;
  1411. a[4] = x3r;
  1412. a[5] = x3i;
  1413. a[6] = x5r;
  1414. a[7] = x5i;
  1415. a[8] = x1r;
  1416. a[9] = x1i;
  1417. a[10] = x6r;
  1418. a[11] = x6i;
  1419. a[12] = x2r;
  1420. a[13] = x2i;
  1421. a[14] = x4r;
  1422. a[15] = x4i;
  1423. }
  1424. void cftf1st(int n, double *a, double *w)
  1425. {
  1426. int j, j0, j1, j2, j3, k, m, mh;
  1427. double wn4r, csc1, csc3, wk1r, wk1i, wk3r, wk3i,
  1428. wd1r, wd1i, wd3r, wd3i;
  1429. double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i,
  1430. y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i;
  1431. mh = n >> 3;
  1432. m = 2 * mh;
  1433. j1 = m;
  1434. j2 = j1 + m;
  1435. j3 = j2 + m;
  1436. x0r = a[0] + a[j2];
  1437. x0i = a[1] + a[j2 + 1];
  1438. x1r = a[0] - a[j2];
  1439. x1i = a[1] - a[j2 + 1];
  1440. x2r = a[j1] + a[j3];
  1441. x2i = a[j1 + 1] + a[j3 + 1];
  1442. x3r = a[j1] - a[j3];
  1443. x3i = a[j1 + 1] - a[j3 + 1];
  1444. a[0] = x0r + x2r;
  1445. a[1] = x0i + x2i;
  1446. a[j1] = x0r - x2r;
  1447. a[j1 + 1] = x0i - x2i;
  1448. a[j2] = x1r - x3i;
  1449. a[j2 + 1] = x1i + x3r;
  1450. a[j3] = x1r + x3i;
  1451. a[j3 + 1] = x1i - x3r;
  1452. wn4r = w[1];
  1453. csc1 = w[2];
  1454. csc3 = w[3];
  1455. wd1r = 1;
  1456. wd1i = 0;
  1457. wd3r = 1;
  1458. wd3i = 0;
  1459. k = 0;
  1460. for (j = 2; j < mh - 2; j += 4) {
  1461. k += 4;
  1462. wk1r = csc1 * (wd1r + w[k]);
  1463. wk1i = csc1 * (wd1i + w[k + 1]);
  1464. wk3r = csc3 * (wd3r + w[k + 2]);
  1465. wk3i = csc3 * (wd3i + w[k + 3]);
  1466. wd1r = w[k];
  1467. wd1i = w[k + 1];
  1468. wd3r = w[k + 2];
  1469. wd3i = w[k + 3];
  1470. j1 = j + m;
  1471. j2 = j1 + m;
  1472. j3 = j2 + m;
  1473. x0r = a[j] + a[j2];
  1474. x0i = a[j + 1] + a[j2 + 1];
  1475. x1r = a[j] - a[j2];
  1476. x1i = a[j + 1] - a[j2 + 1];
  1477. y0r = a[j + 2] + a[j2 + 2];
  1478. y0i = a[j + 3] + a[j2 + 3];
  1479. y1r = a[j + 2] - a[j2 + 2];
  1480. y1i = a[j + 3] - a[j2 + 3];
  1481. x2r = a[j1] + a[j3];
  1482. x2i = a[j1 + 1] + a[j3 + 1];
  1483. x3r = a[j1] - a[j3];
  1484. x3i = a[j1 + 1] - a[j3 + 1];
  1485. y2r = a[j1 + 2] + a[j3 + 2];
  1486. y2i = a[j1 + 3] + a[j3 + 3];
  1487. y3r = a[j1 + 2] - a[j3 + 2];
  1488. y3i = a[j1 + 3] - a[j3 + 3];
  1489. a[j] = x0r + x2r;
  1490. a[j + 1] = x0i + x2i;
  1491. a[j + 2] = y0r + y2r;
  1492. a[j + 3] = y0i + y2i;
  1493. a[j1] = x0r - x2r;
  1494. a[j1 + 1] = x0i - x2i;
  1495. a[j1 + 2] = y0r - y2r;
  1496. a[j1 + 3] = y0i - y2i;
  1497. x0r = x1r - x3i;
  1498. x0i = x1i + x3r;
  1499. a[j2] = wk1r * x0r - wk1i * x0i;
  1500. a[j2 + 1] = wk1r * x0i + wk1i * x0r;
  1501. x0r = y1r - y3i;
  1502. x0i = y1i + y3r;
  1503. a[j2 + 2] = wd1r * x0r - wd1i * x0i;
  1504. a[j2 + 3] = wd1r * x0i + wd1i * x0r;
  1505. x0r = x1r + x3i;
  1506. x0i = x1i - x3r;
  1507. a[j3] = wk3r * x0r + wk3i * x0i;
  1508. a[j3 + 1] = wk3r * x0i - wk3i * x0r;
  1509. x0r = y1r + y3i;
  1510. x0i = y1i - y3r;
  1511. a[j3 + 2] = wd3r * x0r + wd3i * x0i;
  1512. a[j3 + 3] = wd3r * x0i - wd3i * x0r;
  1513. j0 = m - j;
  1514. j1 = j0 + m;
  1515. j2 = j1 + m;
  1516. j3 = j2 + m;
  1517. x0r = a[j0] + a[j2];
  1518. x0i = a[j0 + 1] + a[j2 + 1];
  1519. x1r = a[j0] - a[j2];
  1520. x1i = a[j0 + 1] - a[j2 + 1];
  1521. y0r = a[j0 - 2] + a[j2 - 2];
  1522. y0i = a[j0 - 1] + a[j2 - 1];
  1523. y1r = a[j0 - 2] - a[j2 - 2];
  1524. y1i = a[j0 - 1] - a[j2 - 1];
  1525. x2r = a[j1] + a[j3];
  1526. x2i = a[j1 + 1] + a[j3 + 1];
  1527. x3r = a[j1] - a[j3];
  1528. x3i = a[j1 + 1] - a[j3 + 1];
  1529. y2r = a[j1 - 2] + a[j3 - 2];
  1530. y2i = a[j1 - 1] + a[j3 - 1];
  1531. y3r = a[j1 - 2] - a[j3 - 2];
  1532. y3i = a[j1 - 1] - a[j3 - 1];
  1533. a[j0] = x0r + x2r;
  1534. a[j0 + 1] = x0i + x2i;
  1535. a[j0 - 2] = y0r + y2r;
  1536. a[j0 - 1] = y0i + y2i;
  1537. a[j1] = x0r - x2r;
  1538. a[j1 + 1] = x0i - x2i;
  1539. a[j1 - 2] = y0r - y2r;
  1540. a[j1 - 1] = y0i - y2i;
  1541. x0r = x1r - x3i;
  1542. x0i = x1i + x3r;
  1543. a[j2] = wk1i * x0r - wk1r * x0i;
  1544. a[j2 + 1] = wk1i * x0i + wk1r * x0r;
  1545. x0r = y1r - y3i;
  1546. x0i = y1i + y3r;
  1547. a[j2 - 2] = wd1i * x0r - wd1r * x0i;
  1548. a[j2 - 1] = wd1i * x0i + wd1r * x0r;
  1549. x0r = x1r + x3i;
  1550. x0i = x1i - x3r;
  1551. a[j3] = wk3i * x0r + wk3r * x0i;
  1552. a[j3 + 1] = wk3i * x0i - wk3r * x0r;
  1553. x0r = y1r + y3i;
  1554. x0i = y1i - y3r;
  1555. a[j3 - 2] = wd3i * x0r + wd3r * x0i;
  1556. a[j3 - 1] = wd3i * x0i - wd3r * x0r;
  1557. }
  1558. wk1r = csc1 * (wd1r + wn4r);
  1559. wk1i = csc1 * (wd1i + wn4r);
  1560. wk3r = csc3 * (wd3r - wn4r);
  1561. wk3i = csc3 * (wd3i - wn4r);
  1562. j0 = mh;
  1563. j1 = j0 + m;
  1564. j2 = j1 + m;
  1565. j3 = j2 + m;
  1566. x0r = a[j0 - 2] + a[j2 - 2];
  1567. x0i = a[j0 - 1] + a[j2 - 1];
  1568. x1r = a[j0 - 2] - a[j2 - 2];
  1569. x1i = a[j0 - 1] - a[j2 - 1];
  1570. x2r = a[j1 - 2] + a[j3 - 2];
  1571. x2i = a[j1 - 1] + a[j3 - 1];
  1572. x3r = a[j1 - 2] - a[j3 - 2];
  1573. x3i = a[j1 - 1] - a[j3 - 1];
  1574. a[j0 - 2] = x0r + x2r;
  1575. a[j0 - 1] = x0i + x2i;
  1576. a[j1 - 2] = x0r - x2r;
  1577. a[j1 - 1] = x0i - x2i;
  1578. x0r = x1r - x3i;
  1579. x0i = x1i + x3r;
  1580. a[j2 - 2] = wk1r * x0r - wk1i * x0i;
  1581. a[j2 - 1] = wk1r * x0i + wk1i * x0r;
  1582. x0r = x1r + x3i;
  1583. x0i = x1i - x3r;
  1584. a[j3 - 2] = wk3r * x0r + wk3i * x0i;
  1585. a[j3 - 1] = wk3r * x0i - wk3i * x0r;
  1586. x0r = a[j0] + a[j2];
  1587. x0i = a[j0 + 1] + a[j2 + 1];
  1588. x1r = a[j0] - a[j2];
  1589. x1i = a[j0 + 1] - a[j2 + 1];
  1590. x2r = a[j1] + a[j3];
  1591. x2i = a[j1 + 1] + a[j3 + 1];
  1592. x3r = a[j1] - a[j3];
  1593. x3i = a[j1 + 1] - a[j3 + 1];
  1594. a[j0] = x0r + x2r;
  1595. a[j0 + 1] = x0i + x2i;
  1596. a[j1] = x0r - x2r;
  1597. a[j1 + 1] = x0i - x2i;
  1598. x0r = x1r - x3i;
  1599. x0i = x1i + x3r;
  1600. a[j2] = wn4r * (x0r - x0i);
  1601. a[j2 + 1] = wn4r * (x0i + x0r);
  1602. x0r = x1r + x3i;
  1603. x0i = x1i - x3r;
  1604. a[j3] = -wn4r * (x0r + x0i);
  1605. a[j3 + 1] = -wn4r * (x0i - x0r);
  1606. x0r = a[j0 + 2] + a[j2 + 2];
  1607. x0i = a[j0 + 3] + a[j2 + 3];
  1608. x1r = a[j0 + 2] - a[j2 + 2];
  1609. x1i = a[j0 + 3] - a[j2 + 3];
  1610. x2r = a[j1 + 2] + a[j3 + 2];
  1611. x2i = a[j1 + 3] + a[j3 + 3];
  1612. x3r = a[j1 + 2] - a[j3 + 2];
  1613. x3i = a[j1 + 3] - a[j3 + 3];
  1614. a[j0 + 2] = x0r + x2r;
  1615. a[j0 + 3] = x0i + x2i;
  1616. a[j1 + 2] = x0r - x2r;
  1617. a[j1 + 3] = x0i - x2i;
  1618. x0r = x1r - x3i;
  1619. x0i = x1i + x3r;
  1620. a[j2 + 2] = wk1i * x0r - wk1r * x0i;
  1621. a[j2 + 3] = wk1i * x0i + wk1r * x0r;
  1622. x0r = x1r + x3i;
  1623. x0i = x1i - x3r;
  1624. a[j3 + 2] = wk3i * x0r + wk3r * x0i;
  1625. a[j3 + 3] = wk3i * x0i - wk3r * x0r;
  1626. }
  1627. void cftb1st(int n, double *a, double *w)
  1628. {
  1629. int j, j0, j1, j2, j3, k, m, mh;
  1630. double wn4r, csc1, csc3, wk1r, wk1i, wk3r, wk3i,
  1631. wd1r, wd1i, wd3r, wd3i;
  1632. double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i,
  1633. y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i;
  1634. mh = n >> 3;
  1635. m = 2 * mh;
  1636. j1 = m;
  1637. j2 = j1 + m;
  1638. j3 = j2 + m;
  1639. x0r = a[0] + a[j2];
  1640. x0i = -a[1] - a[j2 + 1];
  1641. x1r = a[0] - a[j2];
  1642. x1i = -a[1] + a[j2 + 1];
  1643. x2r = a[j1] + a[j3];
  1644. x2i = a[j1 + 1] + a[j3 + 1];
  1645. x3r = a[j1] - a[j3];
  1646. x3i = a[j1 + 1] - a[j3 + 1];
  1647. a[0] = x0r + x2r;
  1648. a[1] = x0i - x2i;
  1649. a[j1] = x0r - x2r;
  1650. a[j1 + 1] = x0i + x2i;
  1651. a[j2] = x1r + x3i;
  1652. a[j2 + 1] = x1i + x3r;
  1653. a[j3] = x1r - x3i;
  1654. a[j3 + 1] = x1i - x3r;
  1655. wn4r = w[1];
  1656. csc1 = w[2];
  1657. csc3 = w[3];
  1658. wd1r = 1;
  1659. wd1i = 0;
  1660. wd3r = 1;
  1661. wd3i = 0;
  1662. k = 0;
  1663. for (j = 2; j < mh - 2; j += 4) {
  1664. k += 4;
  1665. wk1r = csc1 * (wd1r + w[k]);
  1666. wk1i = csc1 * (wd1i + w[k + 1]);
  1667. wk3r = csc3 * (wd3r + w[k + 2]);
  1668. wk3i = csc3 * (wd3i + w[k + 3]);
  1669. wd1r = w[k];
  1670. wd1i = w[k + 1];
  1671. wd3r = w[k + 2];
  1672. wd3i = w[k + 3];
  1673. j1 = j + m;
  1674. j2 = j1 + m;
  1675. j3 = j2 + m;
  1676. x0r = a[j] + a[j2];
  1677. x0i = -a[j + 1] - a[j2 + 1];
  1678. x1r = a[j] - a[j2];
  1679. x1i = -a[j + 1] + a[j2 + 1];
  1680. y0r = a[j + 2] + a[j2 + 2];
  1681. y0i = -a[j + 3] - a[j2 + 3];
  1682. y1r = a[j + 2] - a[j2 + 2];
  1683. y1i = -a[j + 3] + a[j2 + 3];
  1684. x2r = a[j1] + a[j3];
  1685. x2i = a[j1 + 1] + a[j3 + 1];
  1686. x3r = a[j1] - a[j3];
  1687. x3i = a[j1 + 1] - a[j3 + 1];
  1688. y2r = a[j1 + 2] + a[j3 + 2];
  1689. y2i = a[j1 + 3] + a[j3 + 3];
  1690. y3r = a[j1 + 2] - a[j3 + 2];
  1691. y3i = a[j1 + 3] - a[j3 + 3];
  1692. a[j] = x0r + x2r;
  1693. a[j + 1] = x0i - x2i;
  1694. a[j + 2] = y0r + y2r;
  1695. a[j + 3] = y0i - y2i;
  1696. a[j1] = x0r - x2r;
  1697. a[j1 + 1] = x0i + x2i;
  1698. a[j1 + 2] = y0r - y2r;
  1699. a[j1 + 3] = y0i + y2i;
  1700. x0r = x1r + x3i;
  1701. x0i = x1i + x3r;
  1702. a[j2] = wk1r * x0r - wk1i * x0i;
  1703. a[j2 + 1] = wk1r * x0i + wk1i * x0r;
  1704. x0r = y1r + y3i;
  1705. x0i = y1i + y3r;
  1706. a[j2 + 2] = wd1r * x0r - wd1i * x0i;
  1707. a[j2 + 3] = wd1r * x0i + wd1i * x0r;
  1708. x0r = x1r - x3i;
  1709. x0i = x1i - x3r;
  1710. a[j3] = wk3r * x0r + wk3i * x0i;
  1711. a[j3 + 1] = wk3r * x0i - wk3i * x0r;
  1712. x0r = y1r - y3i;
  1713. x0i = y1i - y3r;
  1714. a[j3 + 2] = wd3r * x0r + wd3i * x0i;
  1715. a[j3 + 3] = wd3r * x0i - wd3i * x0r;
  1716. j0 = m - j;
  1717. j1 = j0 + m;
  1718. j2 = j1 + m;
  1719. j3 = j2 + m;
  1720. x0r = a[j0] + a[j2];
  1721. x0i = -a[j0 + 1] - a[j2 + 1];
  1722. x1r = a[j0] - a[j2];
  1723. x1i = -a[j0 + 1] + a[j2 + 1];
  1724. y0r = a[j0 - 2] + a[j2 - 2];
  1725. y0i = -a[j0 - 1] - a[j2 - 1];
  1726. y1r = a[j0 - 2] - a[j2 - 2];
  1727. y1i = -a[j0 - 1] + a[j2 - 1];
  1728. x2r = a[j1] + a[j3];
  1729. x2i = a[j1 + 1] + a[j3 + 1];
  1730. x3r = a[j1] - a[j3];
  1731. x3i = a[j1 + 1] - a[j3 + 1];
  1732. y2r = a[j1 - 2] + a[j3 - 2];
  1733. y2i = a[j1 - 1] + a[j3 - 1];
  1734. y3r = a[j1 - 2] - a[j3 - 2];
  1735. y3i = a[j1 - 1] - a[j3 - 1];
  1736. a[j0] = x0r + x2r;
  1737. a[j0 + 1] = x0i - x2i;
  1738. a[j0 - 2] = y0r + y2r;
  1739. a[j0 - 1] = y0i - y2i;
  1740. a[j1] = x0r - x2r;
  1741. a[j1 + 1] = x0i + x2i;
  1742. a[j1 - 2] = y0r - y2r;
  1743. a[j1 - 1] = y0i + y2i;
  1744. x0r = x1r + x3i;
  1745. x0i = x1i + x3r;
  1746. a[j2] = wk1i * x0r - wk1r * x0i;
  1747. a[j2 + 1] = wk1i * x0i + wk1r * x0r;
  1748. x0r = y1r + y3i;
  1749. x0i = y1i + y3r;
  1750. a[j2 - 2] = wd1i * x0r - wd1r * x0i;
  1751. a[j2 - 1] = wd1i * x0i + wd1r * x0r;
  1752. x0r = x1r - x3i;
  1753. x0i = x1i - x3r;
  1754. a[j3] = wk3i * x0r + wk3r * x0i;
  1755. a[j3 + 1] = wk3i * x0i - wk3r * x0r;
  1756. x0r = y1r - y3i;
  1757. x0i = y1i - y3r;
  1758. a[j3 - 2] = wd3i * x0r + wd3r * x0i;
  1759. a[j3 - 1] = wd3i * x0i - wd3r * x0r;
  1760. }
  1761. wk1r = csc1 * (wd1r + wn4r);
  1762. wk1i = csc1 * (wd1i + wn4r);
  1763. wk3r = csc3 * (wd3r - wn4r);
  1764. wk3i = csc3 * (wd3i - wn4r);
  1765. j0 = mh;
  1766. j1 = j0 + m;
  1767. j2 = j1 + m;
  1768. j3 = j2 + m;
  1769. x0r = a[j0 - 2] + a[j2 - 2];
  1770. x0i = -a[j0 - 1] - a[j2 - 1];
  1771. x1r = a[j0 - 2] - a[j2 - 2];
  1772. x1i = -a[j0 - 1] + a[j2 - 1];
  1773. x2r = a[j1 - 2] + a[j3 - 2];
  1774. x2i = a[j1 - 1] + a[j3 - 1];
  1775. x3r = a[j1 - 2] - a[j3 - 2];
  1776. x3i = a[j1 - 1] - a[j3 - 1];
  1777. a[j0 - 2] = x0r + x2r;
  1778. a[j0 - 1] = x0i - x2i;
  1779. a[j1 - 2] = x0r - x2r;
  1780. a[j1 - 1] = x0i + x2i;
  1781. x0r = x1r + x3i;
  1782. x0i = x1i + x3r;
  1783. a[j2 - 2] = wk1r * x0r - wk1i * x0i;
  1784. a[j2 - 1] = wk1r * x0i + wk1i * x0r;
  1785. x0r = x1r - x3i;
  1786. x0i = x1i - x3r;
  1787. a[j3 - 2] = wk3r * x0r + wk3i * x0i;
  1788. a[j3 - 1] = wk3r * x0i - wk3i * x0r;
  1789. x0r = a[j0] + a[j2];
  1790. x0i = -a[j0 + 1] - a[j2 + 1];
  1791. x1r = a[j0] - a[j2];
  1792. x1i = -a[j0 + 1] + a[j2 + 1];
  1793. x2r = a[j1] + a[j3];
  1794. x2i = a[j1 + 1] + a[j3 + 1];
  1795. x3r = a[j1] - a[j3];
  1796. x3i = a[j1 + 1] - a[j3 + 1];
  1797. a[j0] = x0r + x2r;
  1798. a[j0 + 1] = x0i - x2i;
  1799. a[j1] = x0r - x2r;
  1800. a[j1 + 1] = x0i + x2i;
  1801. x0r = x1r + x3i;
  1802. x0i = x1i + x3r;
  1803. a[j2] = wn4r * (x0r - x0i);
  1804. a[j2 + 1] = wn4r * (x0i + x0r);
  1805. x0r = x1r - x3i;
  1806. x0i = x1i - x3r;
  1807. a[j3] = -wn4r * (x0r + x0i);
  1808. a[j3 + 1] = -wn4r * (x0i - x0r);
  1809. x0r = a[j0 + 2] + a[j2 + 2];
  1810. x0i = -a[j0 + 3] - a[j2 + 3];
  1811. x1r = a[j0 + 2] - a[j2 + 2];
  1812. x1i = -a[j0 + 3] + a[j2 + 3];
  1813. x2r = a[j1 + 2] + a[j3 + 2];
  1814. x2i = a[j1 + 3] + a[j3 + 3];
  1815. x3r = a[j1 + 2] - a[j3 + 2];
  1816. x3i = a[j1 + 3] - a[j3 + 3];
  1817. a[j0 + 2] = x0r + x2r;
  1818. a[j0 + 3] = x0i - x2i;
  1819. a[j1 + 2] = x0r - x2r;
  1820. a[j1 + 3] = x0i + x2i;
  1821. x0r = x1r + x3i;
  1822. x0i = x1i + x3r;
  1823. a[j2 + 2] = wk1i * x0r - wk1r * x0i;
  1824. a[j2 + 3] = wk1i * x0i + wk1r * x0r;
  1825. x0r = x1r - x3i;
  1826. x0i = x1i - x3r;
  1827. a[j3 + 2] = wk3i * x0r + wk3r * x0i;
  1828. a[j3 + 3] = wk3i * x0i - wk3r * x0r;
  1829. }
  1830. #ifdef USE_CDFT_THREADS
  1831. struct cdft_arg_st {
  1832. int n0;
  1833. int n;
  1834. double *a;
  1835. int nw;
  1836. double *w;
  1837. };
  1838. typedef struct cdft_arg_st cdft_arg_t;
  1839. void cftrec4_th(int n, double *a, int nw, double *w)
  1840. {
  1841. void *cftrec1_th(void *p);
  1842. void *cftrec2_th(void *p);
  1843. int i, idiv4, m, nthread;
  1844. cdft_thread_t th[4];
  1845. cdft_arg_t ag[4];
  1846. nthread = 2;
  1847. idiv4 = 0;
  1848. m = n >> 1;
  1849. if (n > CDFT_4THREADS_BEGIN_N) {
  1850. nthread = 4;
  1851. idiv4 = 1;
  1852. m >>= 1;
  1853. }
  1854. for (i = 0; i < nthread; i++) {
  1855. ag[i].n0 = n;
  1856. ag[i].n = m;
  1857. ag[i].a = &a[i * m];
  1858. ag[i].nw = nw;
  1859. ag[i].w = w;
  1860. if (i != idiv4) {
  1861. cdft_thread_create(&th[i], cftrec1_th, &ag[i]);
  1862. } else {
  1863. cdft_thread_create(&th[i], cftrec2_th, &ag[i]);
  1864. }
  1865. }
  1866. for (i = 0; i < nthread; i++) {
  1867. cdft_thread_wait(th[i]);
  1868. }
  1869. }
  1870. void *cftrec1_th(void *p)
  1871. {
  1872. int cfttree(int n, int j, int k, double *a, int nw, double *w);
  1873. void cftleaf(int n, int isplt, double *a, int nw, double *w);
  1874. void cftmdl1(int n, double *a, double *w);
  1875. int isplt, j, k, m, n, n0, nw;
  1876. double *a, *w;
  1877. n0 = ((cdft_arg_t *) p)->n0;
  1878. n = ((cdft_arg_t *) p)->n;
  1879. a = ((cdft_arg_t *) p)->a;
  1880. nw = ((cdft_arg_t *) p)->nw;
  1881. w = ((cdft_arg_t *) p)->w;
  1882. m = n0;
  1883. while (m > 512) {
  1884. m >>= 2;
  1885. cftmdl1(m, &a[n - m], &w[nw - (m >> 1)]);
  1886. }
  1887. cftleaf(m, 1, &a[n - m], nw, w);
  1888. k = 0;
  1889. for (j = n - m; j > 0; j -= m) {
  1890. k++;
  1891. isplt = cfttree(m, j, k, a, nw, w);
  1892. cftleaf(m, isplt, &a[j - m], nw, w);
  1893. }
  1894. return (void *) 0;
  1895. }
  1896. void *cftrec2_th(void *p)
  1897. {
  1898. int cfttree(int n, int j, int k, double *a, int nw, double *w);
  1899. void cftleaf(int n, int isplt, double *a, int nw, double *w);
  1900. void cftmdl2(int n, double *a, double *w);
  1901. int isplt, j, k, m, n, n0, nw;
  1902. double *a, *w;
  1903. n0 = ((cdft_arg_t *) p)->n0;
  1904. n = ((cdft_arg_t *) p)->n;
  1905. a = ((cdft_arg_t *) p)->a;
  1906. nw = ((cdft_arg_t *) p)->nw;
  1907. w = ((cdft_arg_t *) p)->w;
  1908. k = 1;
  1909. m = n0;
  1910. while (m > 512) {
  1911. m >>= 2;
  1912. k <<= 2;
  1913. cftmdl2(m, &a[n - m], &w[nw - m]);
  1914. }
  1915. cftleaf(m, 0, &a[n - m], nw, w);
  1916. k >>= 1;
  1917. for (j = n - m; j > 0; j -= m) {
  1918. k++;
  1919. isplt = cfttree(m, j, k, a, nw, w);
  1920. cftleaf(m, isplt, &a[j - m], nw, w);
  1921. }
  1922. return (void *) 0;
  1923. }
  1924. #endif /* USE_CDFT_THREADS */
  1925. void cftrec4(int n, double *a, int nw, double *w)
  1926. {
  1927. int cfttree(int n, int j, int k, double *a, int nw, double *w);
  1928. void cftleaf(int n, int isplt, double *a, int nw, double *w);
  1929. void cftmdl1(int n, double *a, double *w);
  1930. int isplt, j, k, m;
  1931. m = n;
  1932. while (m > 512) {
  1933. m >>= 2;
  1934. cftmdl1(m, &a[n - m], &w[nw - (m >> 1)]);
  1935. }
  1936. cftleaf(m, 1, &a[n - m], nw, w);
  1937. k = 0;
  1938. for (j = n - m; j > 0; j -= m) {
  1939. k++;
  1940. isplt = cfttree(m, j, k, a, nw, w);
  1941. cftleaf(m, isplt, &a[j - m], nw, w);
  1942. }
  1943. }
  1944. int cfttree(int n, int j, int k, double *a, int nw, double *w)
  1945. {
  1946. void cftmdl1(int n, double *a, double *w);
  1947. void cftmdl2(int n, double *a, double *w);
  1948. int i, isplt, m;
  1949. if ((k & 3) != 0) {
  1950. isplt = k & 1;
  1951. if (isplt != 0) {
  1952. cftmdl1(n, &a[j - n], &w[nw - (n >> 1)]);
  1953. } else {
  1954. cftmdl2(n, &a[j - n], &w[nw - n]);
  1955. }
  1956. } else {
  1957. m = n;
  1958. for (i = k; (i & 3) == 0; i >>= 2) {
  1959. m <<= 2;
  1960. }
  1961. isplt = i & 1;
  1962. if (isplt != 0) {
  1963. while (m > 128) {
  1964. cftmdl1(m, &a[j - m], &w[nw - (m >> 1)]);
  1965. m >>= 2;
  1966. }
  1967. } else {
  1968. while (m > 128) {
  1969. cftmdl2(m, &a[j - m], &w[nw - m]);
  1970. m >>= 2;
  1971. }
  1972. }
  1973. }
  1974. return isplt;
  1975. }
  1976. void cftleaf(int n, int isplt, double *a, int nw, double *w)
  1977. {
  1978. void cftmdl1(int n, double *a, double *w);
  1979. void cftmdl2(int n, double *a, double *w);
  1980. void cftf161(double *a, double *w);
  1981. void cftf162(double *a, double *w);
  1982. void cftf081(double *a, double *w);
  1983. void cftf082(double *a, double *w);
  1984. if (n == 512) {
  1985. cftmdl1(128, a, &w[nw - 64]);
  1986. cftf161(a, &w[nw - 8]);
  1987. cftf162(&a[32], &w[nw - 32]);
  1988. cftf161(&a[64], &w[nw - 8]);
  1989. cftf161(&a[96], &w[nw - 8]);
  1990. cftmdl2(128, &a[128], &w[nw - 128]);
  1991. cftf161(&a[128], &w[nw - 8]);
  1992. cftf162(&a[160], &w[nw - 32]);
  1993. cftf161(&a[192], &w[nw - 8]);
  1994. cftf162(&a[224], &w[nw - 32]);
  1995. cftmdl1(128, &a[256], &w[nw - 64]);
  1996. cftf161(&a[256], &w[nw - 8]);
  1997. cftf162(&a[288], &w[nw - 32]);
  1998. cftf161(&a[320], &w[nw - 8]);
  1999. cftf161(&a[352], &w[nw - 8]);
  2000. if (isplt != 0) {
  2001. cftmdl1(128, &a[384], &w[nw - 64]);
  2002. cftf161(&a[480], &w[nw - 8]);
  2003. } else {
  2004. cftmdl2(128, &a[384], &w[nw - 128]);
  2005. cftf162(&a[480], &w[nw - 32]);
  2006. }
  2007. cftf161(&a[384], &w[nw - 8]);
  2008. cftf162(&a[416], &w[nw - 32]);
  2009. cftf161(&a[448], &w[nw - 8]);
  2010. } else {
  2011. cftmdl1(64, a, &w[nw - 32]);
  2012. cftf081(a, &w[nw - 8]);
  2013. cftf082(&a[16], &w[nw - 8]);
  2014. cftf081(&a[32], &w[nw - 8]);
  2015. cftf081(&a[48], &w[nw - 8]);
  2016. cftmdl2(64, &a[64], &w[nw - 64]);
  2017. cftf081(&a[64], &w[nw - 8]);
  2018. cftf082(&a[80], &w[nw - 8]);
  2019. cftf081(&a[96], &w[nw - 8]);
  2020. cftf082(&a[112], &w[nw - 8]);
  2021. cftmdl1(64, &a[128], &w[nw - 32]);
  2022. cftf081(&a[128], &w[nw - 8]);
  2023. cftf082(&a[144], &w[nw - 8]);
  2024. cftf081(&a[160], &w[nw - 8]);
  2025. cftf081(&a[176], &w[nw - 8]);
  2026. if (isplt != 0) {
  2027. cftmdl1(64, &a[192], &w[nw - 32]);
  2028. cftf081(&a[240], &w[nw - 8]);
  2029. } else {
  2030. cftmdl2(64, &a[192], &w[nw - 64]);
  2031. cftf082(&a[240], &w[nw - 8]);
  2032. }
  2033. cftf081(&a[192], &w[nw - 8]);
  2034. cftf082(&a[208], &w[nw - 8]);
  2035. cftf081(&a[224], &w[nw - 8]);
  2036. }
  2037. }
  2038. void cftmdl1(int n, double *a, double *w)
  2039. {
  2040. int j, j0, j1, j2, j3, k, m, mh;
  2041. double wn4r, wk1r, wk1i, wk3r, wk3i;
  2042. double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
  2043. mh = n >> 3;
  2044. m = 2 * mh;
  2045. j1 = m;
  2046. j2 = j1 + m;
  2047. j3 = j2 + m;
  2048. x0r = a[0] + a[j2];
  2049. x0i = a[1] + a[j2 + 1];
  2050. x1r = a[0] - a[j2];
  2051. x1i = a[1] - a[j2 + 1];
  2052. x2r = a[j1] + a[j3];
  2053. x2i = a[j1 + 1] + a[j3 + 1];
  2054. x3r = a[j1] - a[j3];
  2055. x3i = a[j1 + 1] - a[j3 + 1];
  2056. a[0] = x0r + x2r;
  2057. a[1] = x0i + x2i;
  2058. a[j1] = x0r - x2r;
  2059. a[j1 + 1] = x0i - x2i;
  2060. a[j2] = x1r - x3i;
  2061. a[j2 + 1] = x1i + x3r;
  2062. a[j3] = x1r + x3i;
  2063. a[j3 + 1] = x1i - x3r;
  2064. wn4r = w[1];
  2065. k = 0;
  2066. for (j = 2; j < mh; j += 2) {
  2067. k += 4;
  2068. wk1r = w[k];
  2069. wk1i = w[k + 1];
  2070. wk3r = w[k + 2];
  2071. wk3i = w[k + 3];
  2072. j1 = j + m;
  2073. j2 = j1 + m;
  2074. j3 = j2 + m;
  2075. x0r = a[j] + a[j2];
  2076. x0i = a[j + 1] + a[j2 + 1];
  2077. x1r = a[j] - a[j2];
  2078. x1i = a[j + 1] - a[j2 + 1];
  2079. x2r = a[j1] + a[j3];
  2080. x2i = a[j1 + 1] + a[j3 + 1];
  2081. x3r = a[j1] - a[j3];
  2082. x3i = a[j1 + 1] - a[j3 + 1];
  2083. a[j] = x0r + x2r;
  2084. a[j + 1] = x0i + x2i;
  2085. a[j1] = x0r - x2r;
  2086. a[j1 + 1] = x0i - x2i;
  2087. x0r = x1r - x3i;
  2088. x0i = x1i + x3r;
  2089. a[j2] = wk1r * x0r - wk1i * x0i;
  2090. a[j2 + 1] = wk1r * x0i + wk1i * x0r;
  2091. x0r = x1r + x3i;
  2092. x0i = x1i - x3r;
  2093. a[j3] = wk3r * x0r + wk3i * x0i;
  2094. a[j3 + 1] = wk3r * x0i - wk3i * x0r;
  2095. j0 = m - j;
  2096. j1 = j0 + m;
  2097. j2 = j1 + m;
  2098. j3 = j2 + m;
  2099. x0r = a[j0] + a[j2];
  2100. x0i = a[j0 + 1] + a[j2 + 1];
  2101. x1r = a[j0] - a[j2];
  2102. x1i = a[j0 + 1] - a[j2 + 1];
  2103. x2r = a[j1] + a[j3];
  2104. x2i = a[j1 + 1] + a[j3 + 1];
  2105. x3r = a[j1] - a[j3];
  2106. x3i = a[j1 + 1] - a[j3 + 1];
  2107. a[j0] = x0r + x2r;
  2108. a[j0 + 1] = x0i + x2i;
  2109. a[j1] = x0r - x2r;
  2110. a[j1 + 1] = x0i - x2i;
  2111. x0r = x1r - x3i;
  2112. x0i = x1i + x3r;
  2113. a[j2] = wk1i * x0r - wk1r * x0i;
  2114. a[j2 + 1] = wk1i * x0i + wk1r * x0r;
  2115. x0r = x1r + x3i;
  2116. x0i = x1i - x3r;
  2117. a[j3] = wk3i * x0r + wk3r * x0i;
  2118. a[j3 + 1] = wk3i * x0i - wk3r * x0r;
  2119. }
  2120. j0 = mh;
  2121. j1 = j0 + m;
  2122. j2 = j1 + m;
  2123. j3 = j2 + m;
  2124. x0r = a[j0] + a[j2];
  2125. x0i = a[j0 + 1] + a[j2 + 1];
  2126. x1r = a[j0] - a[j2];
  2127. x1i = a[j0 + 1] - a[j2 + 1];
  2128. x2r = a[j1] + a[j3];
  2129. x2i = a[j1 + 1] + a[j3 + 1];
  2130. x3r = a[j1] - a[j3];
  2131. x3i = a[j1 + 1] - a[j3 + 1];
  2132. a[j0] = x0r + x2r;
  2133. a[j0 + 1] = x0i + x2i;
  2134. a[j1] = x0r - x2r;
  2135. a[j1 + 1] = x0i - x2i;
  2136. x0r = x1r - x3i;
  2137. x0i = x1i + x3r;
  2138. a[j2] = wn4r * (x0r - x0i);
  2139. a[j2 + 1] = wn4r * (x0i + x0r);
  2140. x0r = x1r + x3i;
  2141. x0i = x1i - x3r;
  2142. a[j3] = -wn4r * (x0r + x0i);
  2143. a[j3 + 1] = -wn4r * (x0i - x0r);
  2144. }
  2145. void cftmdl2(int n, double *a, double *w)
  2146. {
  2147. int j, j0, j1, j2, j3, k, kr, m, mh;
  2148. double wn4r, wk1r, wk1i, wk3r, wk3i, wd1r, wd1i, wd3r, wd3i;
  2149. double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y2r, y2i;
  2150. mh = n >> 3;
  2151. m = 2 * mh;
  2152. wn4r = w[1];
  2153. j1 = m;
  2154. j2 = j1 + m;
  2155. j3 = j2 + m;
  2156. x0r = a[0] - a[j2 + 1];
  2157. x0i = a[1] + a[j2];
  2158. x1r = a[0] + a[j2 + 1];
  2159. x1i = a[1] - a[j2];
  2160. x2r = a[j1] - a[j3 + 1];
  2161. x2i = a[j1 + 1] + a[j3];
  2162. x3r = a[j1] + a[j3 + 1];
  2163. x3i = a[j1 + 1] - a[j3];
  2164. y0r = wn4r * (x2r - x2i);
  2165. y0i = wn4r * (x2i + x2r);
  2166. a[0] = x0r + y0r;
  2167. a[1] = x0i + y0i;
  2168. a[j1] = x0r - y0r;
  2169. a[j1 + 1] = x0i - y0i;
  2170. y0r = wn4r * (x3r - x3i);
  2171. y0i = wn4r * (x3i + x3r);
  2172. a[j2] = x1r - y0i;
  2173. a[j2 + 1] = x1i + y0r;
  2174. a[j3] = x1r + y0i;
  2175. a[j3 + 1] = x1i - y0r;
  2176. k = 0;
  2177. kr = 2 * m;
  2178. for (j = 2; j < mh; j += 2) {
  2179. k += 4;
  2180. wk1r = w[k];
  2181. wk1i = w[k + 1];
  2182. wk3r = w[k + 2];
  2183. wk3i = w[k + 3];
  2184. kr -= 4;
  2185. wd1i = w[kr];
  2186. wd1r = w[kr + 1];
  2187. wd3i = w[kr + 2];
  2188. wd3r = w[kr + 3];
  2189. j1 = j + m;
  2190. j2 = j1 + m;
  2191. j3 = j2 + m;
  2192. x0r = a[j] - a[j2 + 1];
  2193. x0i = a[j + 1] + a[j2];
  2194. x1r = a[j] + a[j2 + 1];
  2195. x1i = a[j + 1] - a[j2];
  2196. x2r = a[j1] - a[j3 + 1];
  2197. x2i = a[j1 + 1] + a[j3];
  2198. x3r = a[j1] + a[j3 + 1];
  2199. x3i = a[j1 + 1] - a[j3];
  2200. y0r = wk1r * x0r - wk1i * x0i;
  2201. y0i = wk1r * x0i + wk1i * x0r;
  2202. y2r = wd1r * x2r - wd1i * x2i;
  2203. y2i = wd1r * x2i + wd1i * x2r;
  2204. a[j] = y0r + y2r;
  2205. a[j + 1] = y0i + y2i;
  2206. a[j1] = y0r - y2r;
  2207. a[j1 + 1] = y0i - y2i;
  2208. y0r = wk3r * x1r + wk3i * x1i;
  2209. y0i = wk3r * x1i - wk3i * x1r;
  2210. y2r = wd3r * x3r + wd3i * x3i;
  2211. y2i = wd3r * x3i - wd3i * x3r;
  2212. a[j2] = y0r + y2r;
  2213. a[j2 + 1] = y0i + y2i;
  2214. a[j3] = y0r - y2r;
  2215. a[j3 + 1] = y0i - y2i;
  2216. j0 = m - j;
  2217. j1 = j0 + m;
  2218. j2 = j1 + m;
  2219. j3 = j2 + m;
  2220. x0r = a[j0] - a[j2 + 1];
  2221. x0i = a[j0 + 1] + a[j2];
  2222. x1r = a[j0] + a[j2 + 1];
  2223. x1i = a[j0 + 1] - a[j2];
  2224. x2r = a[j1] - a[j3 + 1];
  2225. x2i = a[j1 + 1] + a[j3];
  2226. x3r = a[j1] + a[j3 + 1];
  2227. x3i = a[j1 + 1] - a[j3];
  2228. y0r = wd1i * x0r - wd1r * x0i;
  2229. y0i = wd1i * x0i + wd1r * x0r;
  2230. y2r = wk1i * x2r - wk1r * x2i;
  2231. y2i = wk1i * x2i + wk1r * x2r;
  2232. a[j0] = y0r + y2r;
  2233. a[j0 + 1] = y0i + y2i;
  2234. a[j1] = y0r - y2r;
  2235. a[j1 + 1] = y0i - y2i;
  2236. y0r = wd3i * x1r + wd3r * x1i;
  2237. y0i = wd3i * x1i - wd3r * x1r;
  2238. y2r = wk3i * x3r + wk3r * x3i;
  2239. y2i = wk3i * x3i - wk3r * x3r;
  2240. a[j2] = y0r + y2r;
  2241. a[j2 + 1] = y0i + y2i;
  2242. a[j3] = y0r - y2r;
  2243. a[j3 + 1] = y0i - y2i;
  2244. }
  2245. wk1r = w[m];
  2246. wk1i = w[m + 1];
  2247. j0 = mh;
  2248. j1 = j0 + m;
  2249. j2 = j1 + m;
  2250. j3 = j2 + m;
  2251. x0r = a[j0] - a[j2 + 1];
  2252. x0i = a[j0 + 1] + a[j2];
  2253. x1r = a[j0] + a[j2 + 1];
  2254. x1i = a[j0 + 1] - a[j2];
  2255. x2r = a[j1] - a[j3 + 1];
  2256. x2i = a[j1 + 1] + a[j3];
  2257. x3r = a[j1] + a[j3 + 1];
  2258. x3i = a[j1 + 1] - a[j3];
  2259. y0r = wk1r * x0r - wk1i * x0i;
  2260. y0i = wk1r * x0i + wk1i * x0r;
  2261. y2r = wk1i * x2r - wk1r * x2i;
  2262. y2i = wk1i * x2i + wk1r * x2r;
  2263. a[j0] = y0r + y2r;
  2264. a[j0 + 1] = y0i + y2i;
  2265. a[j1] = y0r - y2r;
  2266. a[j1 + 1] = y0i - y2i;
  2267. y0r = wk1i * x1r - wk1r * x1i;
  2268. y0i = wk1i * x1i + wk1r * x1r;
  2269. y2r = wk1r * x3r - wk1i * x3i;
  2270. y2i = wk1r * x3i + wk1i * x3r;
  2271. a[j2] = y0r - y2r;
  2272. a[j2 + 1] = y0i - y2i;
  2273. a[j3] = y0r + y2r;
  2274. a[j3 + 1] = y0i + y2i;
  2275. }
  2276. void cftfx41(int n, double *a, int nw, double *w)
  2277. {
  2278. void cftf161(double *a, double *w);
  2279. void cftf162(double *a, double *w);
  2280. void cftf081(double *a, double *w);
  2281. void cftf082(double *a, double *w);
  2282. if (n == 128) {
  2283. cftf161(a, &w[nw - 8]);
  2284. cftf162(&a[32], &w[nw - 32]);
  2285. cftf161(&a[64], &w[nw - 8]);
  2286. cftf161(&a[96], &w[nw - 8]);
  2287. } else {
  2288. cftf081(a, &w[nw - 8]);
  2289. cftf082(&a[16], &w[nw - 8]);
  2290. cftf081(&a[32], &w[nw - 8]);
  2291. cftf081(&a[48], &w[nw - 8]);
  2292. }
  2293. }
  2294. void cftf161(double *a, double *w)
  2295. {
  2296. double wn4r, wk1r, wk1i,
  2297. x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i,
  2298. y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i,
  2299. y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i,
  2300. y8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i,
  2301. y12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i;
  2302. wn4r = w[1];
  2303. wk1r = w[2];
  2304. wk1i = w[3];
  2305. x0r = a[0] + a[16];
  2306. x0i = a[1] + a[17];
  2307. x1r = a[0] - a[16];
  2308. x1i = a[1] - a[17];
  2309. x2r = a[8] + a[24];
  2310. x2i = a[9] + a[25];
  2311. x3r = a[8] - a[24];
  2312. x3i = a[9] - a[25];
  2313. y0r = x0r + x2r;
  2314. y0i = x0i + x2i;
  2315. y4r = x0r - x2r;
  2316. y4i = x0i - x2i;
  2317. y8r = x1r - x3i;
  2318. y8i = x1i + x3r;
  2319. y12r = x1r + x3i;
  2320. y12i = x1i - x3r;
  2321. x0r = a[2] + a[18];
  2322. x0i = a[3] + a[19];
  2323. x1r = a[2] - a[18];
  2324. x1i = a[3] - a[19];
  2325. x2r = a[10] + a[26];
  2326. x2i = a[11] + a[27];
  2327. x3r = a[10] - a[26];
  2328. x3i = a[11] - a[27];
  2329. y1r = x0r + x2r;
  2330. y1i = x0i + x2i;
  2331. y5r = x0r - x2r;
  2332. y5i = x0i - x2i;
  2333. x0r = x1r - x3i;
  2334. x0i = x1i + x3r;
  2335. y9r = wk1r * x0r - wk1i * x0i;
  2336. y9i = wk1r * x0i + wk1i * x0r;
  2337. x0r = x1r + x3i;
  2338. x0i = x1i - x3r;
  2339. y13r = wk1i * x0r - wk1r * x0i;
  2340. y13i = wk1i * x0i + wk1r * x0r;
  2341. x0r = a[4] + a[20];
  2342. x0i = a[5] + a[21];
  2343. x1r = a[4] - a[20];
  2344. x1i = a[5] - a[21];
  2345. x2r = a[12] + a[28];
  2346. x2i = a[13] + a[29];
  2347. x3r = a[12] - a[28];
  2348. x3i = a[13] - a[29];
  2349. y2r = x0r + x2r;
  2350. y2i = x0i + x2i;
  2351. y6r = x0r - x2r;
  2352. y6i = x0i - x2i;
  2353. x0r = x1r - x3i;
  2354. x0i = x1i + x3r;
  2355. y10r = wn4r * (x0r - x0i);
  2356. y10i = wn4r * (x0i + x0r);
  2357. x0r = x1r + x3i;
  2358. x0i = x1i - x3r;
  2359. y14r = wn4r * (x0r + x0i);
  2360. y14i = wn4r * (x0i - x0r);
  2361. x0r = a[6] + a[22];
  2362. x0i = a[7] + a[23];
  2363. x1r = a[6] - a[22];
  2364. x1i = a[7] - a[23];
  2365. x2r = a[14] + a[30];
  2366. x2i = a[15] + a[31];
  2367. x3r = a[14] - a[30];
  2368. x3i = a[15] - a[31];
  2369. y3r = x0r + x2r;
  2370. y3i = x0i + x2i;
  2371. y7r = x0r - x2r;
  2372. y7i = x0i - x2i;
  2373. x0r = x1r - x3i;
  2374. x0i = x1i + x3r;
  2375. y11r = wk1i * x0r - wk1r * x0i;
  2376. y11i = wk1i * x0i + wk1r * x0r;
  2377. x0r = x1r + x3i;
  2378. x0i = x1i - x3r;
  2379. y15r = wk1r * x0r - wk1i * x0i;
  2380. y15i = wk1r * x0i + wk1i * x0r;
  2381. x0r = y12r - y14r;
  2382. x0i = y12i - y14i;
  2383. x1r = y12r + y14r;
  2384. x1i = y12i + y14i;
  2385. x2r = y13r - y15r;
  2386. x2i = y13i - y15i;
  2387. x3r = y13r + y15r;
  2388. x3i = y13i + y15i;
  2389. a[24] = x0r + x2r;
  2390. a[25] = x0i + x2i;
  2391. a[26] = x0r - x2r;
  2392. a[27] = x0i - x2i;
  2393. a[28] = x1r - x3i;
  2394. a[29] = x1i + x3r;
  2395. a[30] = x1r + x3i;
  2396. a[31] = x1i - x3r;
  2397. x0r = y8r + y10r;
  2398. x0i = y8i + y10i;
  2399. x1r = y8r - y10r;
  2400. x1i = y8i - y10i;
  2401. x2r = y9r + y11r;
  2402. x2i = y9i + y11i;
  2403. x3r = y9r - y11r;
  2404. x3i = y9i - y11i;
  2405. a[16] = x0r + x2r;
  2406. a[17] = x0i + x2i;
  2407. a[18] = x0r - x2r;
  2408. a[19] = x0i - x2i;
  2409. a[20] = x1r - x3i;
  2410. a[21] = x1i + x3r;
  2411. a[22] = x1r + x3i;
  2412. a[23] = x1i - x3r;
  2413. x0r = y5r - y7i;
  2414. x0i = y5i + y7r;
  2415. x2r = wn4r * (x0r - x0i);
  2416. x2i = wn4r * (x0i + x0r);
  2417. x0r = y5r + y7i;
  2418. x0i = y5i - y7r;
  2419. x3r = wn4r * (x0r - x0i);
  2420. x3i = wn4r * (x0i + x0r);
  2421. x0r = y4r - y6i;
  2422. x0i = y4i + y6r;
  2423. x1r = y4r + y6i;
  2424. x1i = y4i - y6r;
  2425. a[8] = x0r + x2r;
  2426. a[9] = x0i + x2i;
  2427. a[10] = x0r - x2r;
  2428. a[11] = x0i - x2i;
  2429. a[12] = x1r - x3i;
  2430. a[13] = x1i + x3r;
  2431. a[14] = x1r + x3i;
  2432. a[15] = x1i - x3r;
  2433. x0r = y0r + y2r;
  2434. x0i = y0i + y2i;
  2435. x1r = y0r - y2r;
  2436. x1i = y0i - y2i;
  2437. x2r = y1r + y3r;
  2438. x2i = y1i + y3i;
  2439. x3r = y1r - y3r;
  2440. x3i = y1i - y3i;
  2441. a[0] = x0r + x2r;
  2442. a[1] = x0i + x2i;
  2443. a[2] = x0r - x2r;
  2444. a[3] = x0i - x2i;
  2445. a[4] = x1r - x3i;
  2446. a[5] = x1i + x3r;
  2447. a[6] = x1r + x3i;
  2448. a[7] = x1i - x3r;
  2449. }
  2450. void cftf162(double *a, double *w)
  2451. {
  2452. double wn4r, wk1r, wk1i, wk2r, wk2i, wk3r, wk3i,
  2453. x0r, x0i, x1r, x1i, x2r, x2i,
  2454. y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i,
  2455. y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i,
  2456. y8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i,
  2457. y12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i;
  2458. wn4r = w[1];
  2459. wk1r = w[4];
  2460. wk1i = w[5];
  2461. wk3r = w[6];
  2462. wk3i = -w[7];
  2463. wk2r = w[8];
  2464. wk2i = w[9];
  2465. x1r = a[0] - a[17];
  2466. x1i = a[1] + a[16];
  2467. x0r = a[8] - a[25];
  2468. x0i = a[9] + a[24];
  2469. x2r = wn4r * (x0r - x0i);
  2470. x2i = wn4r * (x0i + x0r);
  2471. y0r = x1r + x2r;
  2472. y0i = x1i + x2i;
  2473. y4r = x1r - x2r;
  2474. y4i = x1i - x2i;
  2475. x1r = a[0] + a[17];
  2476. x1i = a[1] - a[16];
  2477. x0r = a[8] + a[25];
  2478. x0i = a[9] - a[24];
  2479. x2r = wn4r * (x0r - x0i);
  2480. x2i = wn4r * (x0i + x0r);
  2481. y8r = x1r - x2i;
  2482. y8i = x1i + x2r;
  2483. y12r = x1r + x2i;
  2484. y12i = x1i - x2r;
  2485. x0r = a[2] - a[19];
  2486. x0i = a[3] + a[18];
  2487. x1r = wk1r * x0r - wk1i * x0i;
  2488. x1i = wk1r * x0i + wk1i * x0r;
  2489. x0r = a[10] - a[27];
  2490. x0i = a[11] + a[26];
  2491. x2r = wk3i * x0r - wk3r * x0i;
  2492. x2i = wk3i * x0i + wk3r * x0r;
  2493. y1r = x1r + x2r;
  2494. y1i = x1i + x2i;
  2495. y5r = x1r - x2r;
  2496. y5i = x1i - x2i;
  2497. x0r = a[2] + a[19];
  2498. x0i = a[3] - a[18];
  2499. x1r = wk3r * x0r - wk3i * x0i;
  2500. x1i = wk3r * x0i + wk3i * x0r;
  2501. x0r = a[10] + a[27];
  2502. x0i = a[11] - a[26];
  2503. x2r = wk1r * x0r + wk1i * x0i;
  2504. x2i = wk1r * x0i - wk1i * x0r;
  2505. y9r = x1r - x2r;
  2506. y9i = x1i - x2i;
  2507. y13r = x1r + x2r;
  2508. y13i = x1i + x2i;
  2509. x0r = a[4] - a[21];
  2510. x0i = a[5] + a[20];
  2511. x1r = wk2r * x0r - wk2i * x0i;
  2512. x1i = wk2r * x0i + wk2i * x0r;
  2513. x0r = a[12] - a[29];
  2514. x0i = a[13] + a[28];
  2515. x2r = wk2i * x0r - wk2r * x0i;
  2516. x2i = wk2i * x0i + wk2r * x0r;
  2517. y2r = x1r + x2r;
  2518. y2i = x1i + x2i;
  2519. y6r = x1r - x2r;
  2520. y6i = x1i - x2i;
  2521. x0r = a[4] + a[21];
  2522. x0i = a[5] - a[20];
  2523. x1r = wk2i * x0r - wk2r * x0i;
  2524. x1i = wk2i * x0i + wk2r * x0r;
  2525. x0r = a[12] + a[29];
  2526. x0i = a[13] - a[28];
  2527. x2r = wk2r * x0r - wk2i * x0i;
  2528. x2i = wk2r * x0i + wk2i * x0r;
  2529. y10r = x1r - x2r;
  2530. y10i = x1i - x2i;
  2531. y14r = x1r + x2r;
  2532. y14i = x1i + x2i;
  2533. x0r = a[6] - a[23];
  2534. x0i = a[7] + a[22];
  2535. x1r = wk3r * x0r - wk3i * x0i;
  2536. x1i = wk3r * x0i + wk3i * x0r;
  2537. x0r = a[14] - a[31];
  2538. x0i = a[15] + a[30];
  2539. x2r = wk1i * x0r - wk1r * x0i;
  2540. x2i = wk1i * x0i + wk1r * x0r;
  2541. y3r = x1r + x2r;
  2542. y3i = x1i + x2i;
  2543. y7r = x1r - x2r;
  2544. y7i = x1i - x2i;
  2545. x0r = a[6] + a[23];
  2546. x0i = a[7] - a[22];
  2547. x1r = wk1i * x0r + wk1r * x0i;
  2548. x1i = wk1i * x0i - wk1r * x0r;
  2549. x0r = a[14] + a[31];
  2550. x0i = a[15] - a[30];
  2551. x2r = wk3i * x0r - wk3r * x0i;
  2552. x2i = wk3i * x0i + wk3r * x0r;
  2553. y11r = x1r + x2r;
  2554. y11i = x1i + x2i;
  2555. y15r = x1r - x2r;
  2556. y15i = x1i - x2i;
  2557. x1r = y0r + y2r;
  2558. x1i = y0i + y2i;
  2559. x2r = y1r + y3r;
  2560. x2i = y1i + y3i;
  2561. a[0] = x1r + x2r;
  2562. a[1] = x1i + x2i;
  2563. a[2] = x1r - x2r;
  2564. a[3] = x1i - x2i;
  2565. x1r = y0r - y2r;
  2566. x1i = y0i - y2i;
  2567. x2r = y1r - y3r;
  2568. x2i = y1i - y3i;
  2569. a[4] = x1r - x2i;
  2570. a[5] = x1i + x2r;
  2571. a[6] = x1r + x2i;
  2572. a[7] = x1i - x2r;
  2573. x1r = y4r - y6i;
  2574. x1i = y4i + y6r;
  2575. x0r = y5r - y7i;
  2576. x0i = y5i + y7r;
  2577. x2r = wn4r * (x0r - x0i);
  2578. x2i = wn4r * (x0i + x0r);
  2579. a[8] = x1r + x2r;
  2580. a[9] = x1i + x2i;
  2581. a[10] = x1r - x2r;
  2582. a[11] = x1i - x2i;
  2583. x1r = y4r + y6i;
  2584. x1i = y4i - y6r;
  2585. x0r = y5r + y7i;
  2586. x0i = y5i - y7r;
  2587. x2r = wn4r * (x0r - x0i);
  2588. x2i = wn4r * (x0i + x0r);
  2589. a[12] = x1r - x2i;
  2590. a[13] = x1i + x2r;
  2591. a[14] = x1r + x2i;
  2592. a[15] = x1i - x2r;
  2593. x1r = y8r + y10r;
  2594. x1i = y8i + y10i;
  2595. x2r = y9r - y11r;
  2596. x2i = y9i - y11i;
  2597. a[16] = x1r + x2r;
  2598. a[17] = x1i + x2i;
  2599. a[18] = x1r - x2r;
  2600. a[19] = x1i - x2i;
  2601. x1r = y8r - y10r;
  2602. x1i = y8i - y10i;
  2603. x2r = y9r + y11r;
  2604. x2i = y9i + y11i;
  2605. a[20] = x1r - x2i;
  2606. a[21] = x1i + x2r;
  2607. a[22] = x1r + x2i;
  2608. a[23] = x1i - x2r;
  2609. x1r = y12r - y14i;
  2610. x1i = y12i + y14r;
  2611. x0r = y13r + y15i;
  2612. x0i = y13i - y15r;
  2613. x2r = wn4r * (x0r - x0i);
  2614. x2i = wn4r * (x0i + x0r);
  2615. a[24] = x1r + x2r;
  2616. a[25] = x1i + x2i;
  2617. a[26] = x1r - x2r;
  2618. a[27] = x1i - x2i;
  2619. x1r = y12r + y14i;
  2620. x1i = y12i - y14r;
  2621. x0r = y13r - y15i;
  2622. x0i = y13i + y15r;
  2623. x2r = wn4r * (x0r - x0i);
  2624. x2i = wn4r * (x0i + x0r);
  2625. a[28] = x1r - x2i;
  2626. a[29] = x1i + x2r;
  2627. a[30] = x1r + x2i;
  2628. a[31] = x1i - x2r;
  2629. }
  2630. void cftf081(double *a, double *w)
  2631. {
  2632. double wn4r, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i,
  2633. y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i,
  2634. y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i;
  2635. wn4r = w[1];
  2636. x0r = a[0] + a[8];
  2637. x0i = a[1] + a[9];
  2638. x1r = a[0] - a[8];
  2639. x1i = a[1] - a[9];
  2640. x2r = a[4] + a[12];
  2641. x2i = a[5] + a[13];
  2642. x3r = a[4] - a[12];
  2643. x3i = a[5] - a[13];
  2644. y0r = x0r + x2r;
  2645. y0i = x0i + x2i;
  2646. y2r = x0r - x2r;
  2647. y2i = x0i - x2i;
  2648. y1r = x1r - x3i;
  2649. y1i = x1i + x3r;
  2650. y3r = x1r + x3i;
  2651. y3i = x1i - x3r;
  2652. x0r = a[2] + a[10];
  2653. x0i = a[3] + a[11];
  2654. x1r = a[2] - a[10];
  2655. x1i = a[3] - a[11];
  2656. x2r = a[6] + a[14];
  2657. x2i = a[7] + a[15];
  2658. x3r = a[6] - a[14];
  2659. x3i = a[7] - a[15];
  2660. y4r = x0r + x2r;
  2661. y4i = x0i + x2i;
  2662. y6r = x0r - x2r;
  2663. y6i = x0i - x2i;
  2664. x0r = x1r - x3i;
  2665. x0i = x1i + x3r;
  2666. x2r = x1r + x3i;
  2667. x2i = x1i - x3r;
  2668. y5r = wn4r * (x0r - x0i);
  2669. y5i = wn4r * (x0r + x0i);
  2670. y7r = wn4r * (x2r - x2i);
  2671. y7i = wn4r * (x2r + x2i);
  2672. a[8] = y1r + y5r;
  2673. a[9] = y1i + y5i;
  2674. a[10] = y1r - y5r;
  2675. a[11] = y1i - y5i;
  2676. a[12] = y3r - y7i;
  2677. a[13] = y3i + y7r;
  2678. a[14] = y3r + y7i;
  2679. a[15] = y3i - y7r;
  2680. a[0] = y0r + y4r;
  2681. a[1] = y0i + y4i;
  2682. a[2] = y0r - y4r;
  2683. a[3] = y0i - y4i;
  2684. a[4] = y2r - y6i;
  2685. a[5] = y2i + y6r;
  2686. a[6] = y2r + y6i;
  2687. a[7] = y2i - y6r;
  2688. }
  2689. void cftf082(double *a, double *w)
  2690. {
  2691. double wn4r, wk1r, wk1i, x0r, x0i, x1r, x1i,
  2692. y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i,
  2693. y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i;
  2694. wn4r = w[1];
  2695. wk1r = w[2];
  2696. wk1i = w[3];
  2697. y0r = a[0] - a[9];
  2698. y0i = a[1] + a[8];
  2699. y1r = a[0] + a[9];
  2700. y1i = a[1] - a[8];
  2701. x0r = a[4] - a[13];
  2702. x0i = a[5] + a[12];
  2703. y2r = wn4r * (x0r - x0i);
  2704. y2i = wn4r * (x0i + x0r);
  2705. x0r = a[4] + a[13];
  2706. x0i = a[5] - a[12];
  2707. y3r = wn4r * (x0r - x0i);
  2708. y3i = wn4r * (x0i + x0r);
  2709. x0r = a[2] - a[11];
  2710. x0i = a[3] + a[10];
  2711. y4r = wk1r * x0r - wk1i * x0i;
  2712. y4i = wk1r * x0i + wk1i * x0r;
  2713. x0r = a[2] + a[11];
  2714. x0i = a[3] - a[10];
  2715. y5r = wk1i * x0r - wk1r * x0i;
  2716. y5i = wk1i * x0i + wk1r * x0r;
  2717. x0r = a[6] - a[15];
  2718. x0i = a[7] + a[14];
  2719. y6r = wk1i * x0r - wk1r * x0i;
  2720. y6i = wk1i * x0i + wk1r * x0r;
  2721. x0r = a[6] + a[15];
  2722. x0i = a[7] - a[14];
  2723. y7r = wk1r * x0r - wk1i * x0i;
  2724. y7i = wk1r * x0i + wk1i * x0r;
  2725. x0r = y0r + y2r;
  2726. x0i = y0i + y2i;
  2727. x1r = y4r + y6r;
  2728. x1i = y4i + y6i;
  2729. a[0] = x0r + x1r;
  2730. a[1] = x0i + x1i;
  2731. a[2] = x0r - x1r;
  2732. a[3] = x0i - x1i;
  2733. x0r = y0r - y2r;
  2734. x0i = y0i - y2i;
  2735. x1r = y4r - y6r;
  2736. x1i = y4i - y6i;
  2737. a[4] = x0r - x1i;
  2738. a[5] = x0i + x1r;
  2739. a[6] = x0r + x1i;
  2740. a[7] = x0i - x1r;
  2741. x0r = y1r - y3i;
  2742. x0i = y1i + y3r;
  2743. x1r = y5r - y7r;
  2744. x1i = y5i - y7i;
  2745. a[8] = x0r + x1r;
  2746. a[9] = x0i + x1i;
  2747. a[10] = x0r - x1r;
  2748. a[11] = x0i - x1i;
  2749. x0r = y1r + y3i;
  2750. x0i = y1i - y3r;
  2751. x1r = y5r + y7r;
  2752. x1i = y5i + y7i;
  2753. a[12] = x0r - x1i;
  2754. a[13] = x0i + x1r;
  2755. a[14] = x0r + x1i;
  2756. a[15] = x0i - x1r;
  2757. }
  2758. void cftf040(double *a)
  2759. {
  2760. double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
  2761. x0r = a[0] + a[4];
  2762. x0i = a[1] + a[5];
  2763. x1r = a[0] - a[4];
  2764. x1i = a[1] - a[5];
  2765. x2r = a[2] + a[6];
  2766. x2i = a[3] + a[7];
  2767. x3r = a[2] - a[6];
  2768. x3i = a[3] - a[7];
  2769. a[0] = x0r + x2r;
  2770. a[1] = x0i + x2i;
  2771. a[2] = x1r - x3i;
  2772. a[3] = x1i + x3r;
  2773. a[4] = x0r - x2r;
  2774. a[5] = x0i - x2i;
  2775. a[6] = x1r + x3i;
  2776. a[7] = x1i - x3r;
  2777. }
  2778. void cftb040(double *a)
  2779. {
  2780. double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
  2781. x0r = a[0] + a[4];
  2782. x0i = a[1] + a[5];
  2783. x1r = a[0] - a[4];
  2784. x1i = a[1] - a[5];
  2785. x2r = a[2] + a[6];
  2786. x2i = a[3] + a[7];
  2787. x3r = a[2] - a[6];
  2788. x3i = a[3] - a[7];
  2789. a[0] = x0r + x2r;
  2790. a[1] = x0i + x2i;
  2791. a[2] = x1r + x3i;
  2792. a[3] = x1i - x3r;
  2793. a[4] = x0r - x2r;
  2794. a[5] = x0i - x2i;
  2795. a[6] = x1r - x3i;
  2796. a[7] = x1i + x3r;
  2797. }
  2798. void cftx020(double *a)
  2799. {
  2800. double x0r, x0i;
  2801. x0r = a[0] - a[2];
  2802. x0i = a[1] - a[3];
  2803. a[0] += a[2];
  2804. a[1] += a[3];
  2805. a[2] = x0r;
  2806. a[3] = x0i;
  2807. }
  2808. void rftfsub(int n, double *a, int nc, double *c)
  2809. {
  2810. int j, k, kk, ks, m;
  2811. double wkr, wki, xr, xi, yr, yi;
  2812. m = n >> 1;
  2813. ks = 2 * nc / m;
  2814. kk = 0;
  2815. for (j = 2; j < m; j += 2) {
  2816. k = n - j;
  2817. kk += ks;
  2818. wkr = 0.5 - c[nc - kk];
  2819. wki = c[kk];
  2820. xr = a[j] - a[k];
  2821. xi = a[j + 1] + a[k + 1];
  2822. yr = wkr * xr - wki * xi;
  2823. yi = wkr * xi + wki * xr;
  2824. a[j] -= yr;
  2825. a[j + 1] -= yi;
  2826. a[k] += yr;
  2827. a[k + 1] -= yi;
  2828. }
  2829. }
  2830. void rftbsub(int n, double *a, int nc, double *c)
  2831. {
  2832. int j, k, kk, ks, m;
  2833. double wkr, wki, xr, xi, yr, yi;
  2834. m = n >> 1;
  2835. ks = 2 * nc / m;
  2836. kk = 0;
  2837. for (j = 2; j < m; j += 2) {
  2838. k = n - j;
  2839. kk += ks;
  2840. wkr = 0.5 - c[nc - kk];
  2841. wki = c[kk];
  2842. xr = a[j] - a[k];
  2843. xi = a[j + 1] + a[k + 1];
  2844. yr = wkr * xr + wki * xi;
  2845. yi = wkr * xi - wki * xr;
  2846. a[j] -= yr;
  2847. a[j + 1] -= yi;
  2848. a[k] += yr;
  2849. a[k + 1] -= yi;
  2850. }
  2851. }