~ chicken-core (chicken-5) a2eee7ac4fa8053a0c444b4b94cf97f6ae997628
commit a2eee7ac4fa8053a0c444b4b94cf97f6ae997628 Author: unknown <felix@.(none)> AuthorDate: Wed Nov 4 13:08:02 2009 +0100 Commit: unknown <felix@.(none)> CommitDate: Wed Nov 4 13:08:02 2009 +0100 added Brad Luciers fft benchmark to test suite diff --git a/tests/fft.scm b/tests/fft.scm new file mode 100644 index 00000000..726ec292 --- /dev/null +++ b/tests/fft.scm @@ -0,0 +1,2071 @@ +(declare (standard-bindings) + (extended-bindings) + (block) + (not safe) + ) + +;;; All the following redefinitions are *ignored* by the Gambit compiler +;;; because of the declarations above. + +(cond-expand + (chicken + (begin + (use srfi-4) + (define-syntax defalias + (syntax-rules () + ((_ one two) + (define-syntax one + (syntax-rules () + ((_ . args) (two . args))))))) + (defalias fixnum->flonum exact->inexact) + (defalias fxodd? odd?) + (defalias fxeven? even?) + (defalias fxarithmetic-shift-right fxshr) + (defalias fxarithmetic-shift-left fxshl) + (defalias fl* fp*) + (defalias fl/ fp/) + (defalias fl+ fp+) + (defalias fl- fp-) + (defalias flsqrt sqrt))) + (else)) + +(cond-expand + ((and chicken (not unboxed)) + (begin + (defalias make-f64vector make-vector) + (defalias f64vector vector) + (defalias f64vector-set! vector-set!) + (defalias f64vector-ref vector-ref) + (defalias list->f64vector list->vector) + (defalias f64vector-length vector-length)) ) + (else) ) + +;;; end of *ignored* definitions + +(define lut-table-size 512) +(define lut-table-size^2 262144) +(define lut-table-size^3 134217728) +(define log-lut-table-size 9) + +(define low-lut + (list->f64vector '(1. 0. + .7071067811865476 .7071067811865476 + .9238795325112867 .3826834323650898 + .3826834323650898 .9238795325112867 + .9807852804032304 .19509032201612828 + .5555702330196022 .8314696123025452 + .8314696123025452 .5555702330196022 + .19509032201612828 .9807852804032304 + .9951847266721969 .0980171403295606 + .6343932841636455 .773010453362737 + .881921264348355 .47139673682599764 + .2902846772544624 .9569403357322088 + .9569403357322088 .2902846772544624 + .47139673682599764 .881921264348355 + .773010453362737 .6343932841636455 + .0980171403295606 .9951847266721969 + .9987954562051724 .049067674327418015 + .6715589548470184 .7409511253549591 + .9039892931234433 .4275550934302821 + .33688985339222005 .9415440651830208 + .970031253194544 .2429801799032639 + .5141027441932218 .8577286100002721 + .8032075314806449 .5956993044924334 + .14673047445536175 .989176509964781 + .989176509964781 .14673047445536175 + .5956993044924334 .8032075314806449 + .8577286100002721 .5141027441932218 + .2429801799032639 .970031253194544 + .9415440651830208 .33688985339222005 + .4275550934302821 .9039892931234433 + .7409511253549591 .6715589548470184 + .049067674327418015 .9987954562051724 + .9996988186962042 .024541228522912288 + .6895405447370669 .7242470829514669 + .9142097557035307 .40524131400498986 + .35989503653498817 .9329927988347388 + .9757021300385286 .2191012401568698 + .5349976198870973 .8448535652497071 + .8175848131515837 .5758081914178453 + .17096188876030122 .9852776423889412 + .99247953459871 .1224106751992162 + .6152315905806268 .7883464276266062 + .8700869911087115 .49289819222978404 + .26671275747489837 .9637760657954398 + .9495281805930367 .31368174039889146 + .4496113296546066 .8932243011955153 + .7572088465064846 .6531728429537768 + .07356456359966743 .9972904566786902 + .9972904566786902 .07356456359966743 + .6531728429537768 .7572088465064846 + .8932243011955153 .4496113296546066 + .31368174039889146 .9495281805930367 + .9637760657954398 .26671275747489837 + .49289819222978404 .8700869911087115 + .7883464276266062 .6152315905806268 + .1224106751992162 .99247953459871 + .9852776423889412 .17096188876030122 + .5758081914178453 .8175848131515837 + .8448535652497071 .5349976198870973 + .2191012401568698 .9757021300385286 + .9329927988347388 .35989503653498817 + .40524131400498986 .9142097557035307 + .7242470829514669 .6895405447370669 + .024541228522912288 .9996988186962042 + .9999247018391445 .012271538285719925 + .6983762494089728 .7157308252838187 + .9191138516900578 .3939920400610481 + .37131719395183754 .9285060804732156 + .9783173707196277 .20711137619221856 + .5453249884220465 .8382247055548381 + .8245893027850253 .5657318107836132 + .18303988795514095 .9831054874312163 + .9939069700023561 .11022220729388306 + .6248594881423863 .7807372285720945 + .8760700941954066 .4821837720791228 + .2785196893850531 .9604305194155658 + .9533060403541939 .3020059493192281 + .46053871095824 .8876396204028539 + .765167265622459 .6438315428897915 + .0857973123444399 .996312612182778 + .9981181129001492 .06132073630220858 + .6624157775901718 .7491363945234594 + .8986744656939538 .43861623853852766 + .3253102921622629 .9456073253805213 + .9669764710448521 .25486565960451457 + .5035383837257176 .8639728561215867 + .7958369046088836 .6055110414043255 + .1345807085071262 .99090263542778 + .9873014181578584 .15885814333386145 + .5857978574564389 .8104571982525948 + .8513551931052652 .524589682678469 + .2310581082806711 .9729399522055602 + .937339011912575 .34841868024943456 + .4164295600976372 .9091679830905224 + .7326542716724128 .680600997795453 + .03680722294135883 .9993223845883495 + .9993223845883495 .03680722294135883 + .680600997795453 .7326542716724128 + .9091679830905224 .4164295600976372 + .34841868024943456 .937339011912575 + .9729399522055602 .2310581082806711 + .524589682678469 .8513551931052652 + .8104571982525948 .5857978574564389 + .15885814333386145 .9873014181578584 + .99090263542778 .1345807085071262 + .6055110414043255 .7958369046088836 + .8639728561215867 .5035383837257176 + .25486565960451457 .9669764710448521 + .9456073253805213 .3253102921622629 + .43861623853852766 .8986744656939538 + .7491363945234594 .6624157775901718 + .06132073630220858 .9981181129001492 + .996312612182778 .0857973123444399 + .6438315428897915 .765167265622459 + .8876396204028539 .46053871095824 + .3020059493192281 .9533060403541939 + .9604305194155658 .2785196893850531 + .4821837720791228 .8760700941954066 + .7807372285720945 .6248594881423863 + .11022220729388306 .9939069700023561 + .9831054874312163 .18303988795514095 + .5657318107836132 .8245893027850253 + .8382247055548381 .5453249884220465 + .20711137619221856 .9783173707196277 + .9285060804732156 .37131719395183754 + .3939920400610481 .9191138516900578 + .7157308252838187 .6983762494089728 + .012271538285719925 .9999247018391445 + .9999811752826011 .006135884649154475 + .7027547444572253 .7114321957452164 + .9215140393420419 .3883450466988263 + .37700741021641826 .9262102421383114 + .9795697656854405 .2011046348420919 + .5504579729366048 .83486287498638 + .8280450452577558 .560661576197336 + .18906866414980622 .9819638691095552 + .9945645707342554 .10412163387205457 + .629638238914927 .7768884656732324 + .8790122264286335 .47679923006332214 + .2844075372112718 .9587034748958716 + .9551411683057707 .29615088824362384 + .4659764957679662 .8847970984309378 + .7691033376455796 .6391244448637757 + .09190895649713272 .9957674144676598 + .9984755805732948 .05519524434968994 + .6669999223036375 .745057785441466 + .901348847046022 .43309381885315196 + .33110630575987643 .9435934581619604 + .9685220942744173 .24892760574572018 + .508830142543107 .8608669386377673 + .799537269107905 .600616479383869 + .14065823933284924 .9900582102622971 + .9882575677307495 .15279718525844344 + .5907597018588743 .8068475535437992 + .8545579883654005 .5193559901655896 + .2370236059943672 .9715038909862518 + .9394592236021899 .3426607173119944 + .4220002707997997 .9065957045149153 + .7368165688773699 .6760927035753159 + .04293825693494082 .9990777277526454 + .9995294175010931 .030674803176636626 + .6850836677727004 .7284643904482252 + .9117060320054299 .41084317105790397 + .3541635254204904 .9351835099389476 + .9743393827855759 .22508391135979283 + .5298036246862947 .8481203448032972 + .8140363297059484 .5808139580957645 + .16491312048996992 .9863080972445987 + .9917097536690995 .12849811079379317 + .6103828062763095 .7921065773002124 + .8670462455156926 .49822766697278187 + .2607941179152755 .9653944416976894 + .9475855910177411 .3195020308160157 + .44412214457042926 .8959662497561851 + .7531867990436125 .6578066932970786 + .06744391956366406 .9977230666441916 + .9968202992911657 .07968243797143013 + .6485144010221124 .7612023854842618 + .8904487232447579 .45508358712634384 + .30784964004153487 .9514350209690083 + .9621214042690416 .272621355449949 + .48755016014843594 .8730949784182901 + .7845565971555752 .6200572117632892 + .11631863091190477 .9932119492347945 + .984210092386929 .17700422041214875 + .5707807458869673 .8211025149911046 + .8415549774368984 .5401714727298929 + .21311031991609136 .9770281426577544 + .9307669610789837 .36561299780477385 + .39962419984564684 .9166790599210427 + .7200025079613817 .693971460889654 + .01840672990580482 .9998305817958234 + .9998305817958234 .01840672990580482 + .693971460889654 .7200025079613817 + .9166790599210427 .39962419984564684 + .36561299780477385 .9307669610789837 + .9770281426577544 .21311031991609136 + .5401714727298929 .8415549774368984 + .8211025149911046 .5707807458869673 + .17700422041214875 .984210092386929 + .9932119492347945 .11631863091190477 + .6200572117632892 .7845565971555752 + .8730949784182901 .48755016014843594 + .272621355449949 .9621214042690416 + .9514350209690083 .30784964004153487 + .45508358712634384 .8904487232447579 + .7612023854842618 .6485144010221124 + .07968243797143013 .9968202992911657 + .9977230666441916 .06744391956366406 + .6578066932970786 .7531867990436125 + .8959662497561851 .44412214457042926 + .3195020308160157 .9475855910177411 + .9653944416976894 .2607941179152755 + .49822766697278187 .8670462455156926 + .7921065773002124 .6103828062763095 + .12849811079379317 .9917097536690995 + .9863080972445987 .16491312048996992 + .5808139580957645 .8140363297059484 + .8481203448032972 .5298036246862947 + .22508391135979283 .9743393827855759 + .9351835099389476 .3541635254204904 + .41084317105790397 .9117060320054299 + .7284643904482252 .6850836677727004 + .030674803176636626 .9995294175010931 + .9990777277526454 .04293825693494082 + .6760927035753159 .7368165688773699 + .9065957045149153 .4220002707997997 + .3426607173119944 .9394592236021899 + .9715038909862518 .2370236059943672 + .5193559901655896 .8545579883654005 + .8068475535437992 .5907597018588743 + .15279718525844344 .9882575677307495 + .9900582102622971 .14065823933284924 + .600616479383869 .799537269107905 + .8608669386377673 .508830142543107 + .24892760574572018 .9685220942744173 + .9435934581619604 .33110630575987643 + .43309381885315196 .901348847046022 + .745057785441466 .6669999223036375 + .05519524434968994 .9984755805732948 + .9957674144676598 .09190895649713272 + .6391244448637757 .7691033376455796 + .8847970984309378 .4659764957679662 + .29615088824362384 .9551411683057707 + .9587034748958716 .2844075372112718 + .47679923006332214 .8790122264286335 + .7768884656732324 .629638238914927 + .10412163387205457 .9945645707342554 + .9819638691095552 .18906866414980622 + .560661576197336 .8280450452577558 + .83486287498638 .5504579729366048 + .2011046348420919 .9795697656854405 + .9262102421383114 .37700741021641826 + .3883450466988263 .9215140393420419 + .7114321957452164 .7027547444572253 + .006135884649154475 .9999811752826011 + .9999952938095762 .003067956762965976 + .7049340803759049 .7092728264388657 + .9227011283338785 .38551605384391885 + .37984720892405116 .9250492407826776 + .9801821359681174 .1980984107179536 + .5530167055800276 .8331701647019132 + .829761233794523 .5581185312205561 + .19208039704989244 .9813791933137546 + .9948793307948056 .10106986275482782 + .6320187359398091 .7749531065948739 + .8804708890521608 .47410021465055 + .2873474595447295 .9578264130275329 + .9560452513499964 .29321916269425863 + .46868882203582796 .8833633386657316 + .7710605242618138 .6367618612362842 + .094963495329639 .9954807554919269 + .9986402181802653 .052131704680283324 + .6692825883466361 .7430079521351217 + .9026733182372588 .4303264813400826 + .3339996514420094 .9425731976014469 + .9692812353565485 .24595505033579462 + .5114688504379704 .8593018183570084 + .8013761717231402 .5981607069963423 + .14369503315029444 .9896220174632009 + .9887216919603238 .1497645346773215 + .5932322950397998 .8050313311429635 + .8561473283751945 .5167317990176499 + .2400030224487415 .9707721407289504 + .9405060705932683 .33977688440682685 + .4247796812091088 .9052967593181188 + .7388873244606151 .673829000378756 + .04600318213091463 .9989412931868569 + .9996188224951786 .027608145778965743 + .6873153408917592 .726359155084346 + .9129621904283982 .4080441628649787 + .35703096123343003 .9340925504042589 + .9750253450669941 .22209362097320354 + .532403127877198 .8464909387740521 + .8158144108067338 .5783137964116556 + .16793829497473117 .9857975091675675 + .9920993131421918 .12545498341154623 + .6128100824294097 .79023022143731 + .8685707059713409 .49556526182577254 + .2637546789748314 .9645897932898128 + .9485613499157303 .31659337555616585 + .4468688401623742 .8945994856313827 + .7552013768965365 .6554928529996153 + .07050457338961387 .9975114561403035 + .997060070339483 .07662386139203149 + .6508466849963809 .7592091889783881 + .8918407093923427 .4523495872337709 + .3107671527496115 .9504860739494817 + .9629532668736839 .2696683255729151 + .49022648328829116 .8715950866559511 + .7864552135990858 .617647307937804 + .11936521481099137 .9928504144598651 + .9847485018019042 .17398387338746382 + .5732971666980422 .819347520076797 + .8432082396418454 .5375870762956455 + .21610679707621952 .9763697313300211 + .9318842655816681 .3627557243673972 + .40243465085941843 .9154487160882678 + .7221281939292153 .6917592583641577 + .021474080275469508 .9997694053512153 + .9998823474542126 .015339206284988102 + .696177131491463 .7178700450557317 + .9179007756213905 .3968099874167103 + .3684668299533723 .9296408958431812 + .9776773578245099 .2101118368804696 + .5427507848645159 .8398937941959995 + .8228497813758263 .5682589526701316 + .18002290140569951 .9836624192117303 + .9935641355205953 .11327095217756435 + .62246127937415 .7826505961665757 + .8745866522781761 .4848692480007911 + .27557181931095814 .9612804858113206 + .9523750127197659 .30492922973540243 + .45781330359887723 .8890483558546646 + .7631884172633813 .6461760129833164 + .08274026454937569 .9965711457905548 + .997925286198596 .06438263092985747 + .6601143420674205 .7511651319096864 + .8973245807054183 .44137126873171667 + .32240767880106985 .9466009130832835 + .9661900034454125 .257831102162159 + .5008853826112408 .8655136240905691 + .7939754775543372 .6079497849677736 + .13154002870288312 .9913108598461154 + .9868094018141855 .16188639378011183 + .5833086529376983 .8122505865852039 + .8497417680008524 .5271991347819014 + .22807208317088573 .973644249650812 + .9362656671702783 .35129275608556715 + .41363831223843456 .9104412922580672 + .7305627692278276 .6828455463852481 + .03374117185137759 .9994306045554617 + .9992047586183639 .03987292758773981 + .6783500431298615 .7347388780959635 + .9078861164876663 .41921688836322396 + .34554132496398904 .9384035340631081 + .9722264970789363 .23404195858354343 + .5219752929371544 .8529606049303636 + .808656181588175 .5882815482226453 + .15582839765426523 .9877841416445722 + .9904850842564571 .13762012158648604 + .6030665985403482 .7976908409433912 + .8624239561110405 .5061866453451553 + .25189781815421697 .9677538370934755 + .9446048372614803 .32820984357909255 + .4358570799222555 .9000158920161603 + .7471006059801801 .6647109782033449 + .05825826450043576 .9983015449338929 + .996044700901252 .0888535525825246 + .6414810128085832 .7671389119358204 + .8862225301488806 .4632597835518602 + .2990798263080405 .9542280951091057 + .9595715130819845 .281464937925758 + .479493757660153 .8775452902072612 + .778816512381476 .6272518154951441 + .10717242495680884 .9942404494531879 + .9825393022874412 .18605515166344666 + .5631993440138341 .8263210628456635 + .836547727223512 .5478940591731002 + .20410896609281687 .9789481753190622 + .9273625256504011 .374164062971458 + .39117038430225387 .9203182767091106 + .7135848687807936 .7005687939432483 + .00920375478205982 .9999576445519639 + .9999576445519639 .00920375478205982 + .7005687939432483 .7135848687807936 + .9203182767091106 .39117038430225387 + .374164062971458 .9273625256504011 + .9789481753190622 .20410896609281687 + .5478940591731002 .836547727223512 + .8263210628456635 .5631993440138341 + .18605515166344666 .9825393022874412 + .9942404494531879 .10717242495680884 + .6272518154951441 .778816512381476 + .8775452902072612 .479493757660153 + .281464937925758 .9595715130819845 + .9542280951091057 .2990798263080405 + .4632597835518602 .8862225301488806 + .7671389119358204 .6414810128085832 + .0888535525825246 .996044700901252 + .9983015449338929 .05825826450043576 + .6647109782033449 .7471006059801801 + .9000158920161603 .4358570799222555 + .32820984357909255 .9446048372614803 + .9677538370934755 .25189781815421697 + .5061866453451553 .8624239561110405 + .7976908409433912 .6030665985403482 + .13762012158648604 .9904850842564571 + .9877841416445722 .15582839765426523 + .5882815482226453 .808656181588175 + .8529606049303636 .5219752929371544 + .23404195858354343 .9722264970789363 + .9384035340631081 .34554132496398904 + .41921688836322396 .9078861164876663 + .7347388780959635 .6783500431298615 + .03987292758773981 .9992047586183639 + .9994306045554617 .03374117185137759 + .6828455463852481 .7305627692278276 + .9104412922580672 .41363831223843456 + .35129275608556715 .9362656671702783 + .973644249650812 .22807208317088573 + .5271991347819014 .8497417680008524 + .8122505865852039 .5833086529376983 + .16188639378011183 .9868094018141855 + .9913108598461154 .13154002870288312 + .6079497849677736 .7939754775543372 + .8655136240905691 .5008853826112408 + .257831102162159 .9661900034454125 + .9466009130832835 .32240767880106985 + .44137126873171667 .8973245807054183 + .7511651319096864 .6601143420674205 + .06438263092985747 .997925286198596 + .9965711457905548 .08274026454937569 + .6461760129833164 .7631884172633813 + .8890483558546646 .45781330359887723 + .30492922973540243 .9523750127197659 + .9612804858113206 .27557181931095814 + .4848692480007911 .8745866522781761 + .7826505961665757 .62246127937415 + .11327095217756435 .9935641355205953 + .9836624192117303 .18002290140569951 + .5682589526701316 .8228497813758263 + .8398937941959995 .5427507848645159 + .2101118368804696 .9776773578245099 + .9296408958431812 .3684668299533723 + .3968099874167103 .9179007756213905 + .7178700450557317 .696177131491463 + .015339206284988102 .9998823474542126 + .9997694053512153 .021474080275469508 + .6917592583641577 .7221281939292153 + .9154487160882678 .40243465085941843 + .3627557243673972 .9318842655816681 + .9763697313300211 .21610679707621952 + .5375870762956455 .8432082396418454 + .819347520076797 .5732971666980422 + .17398387338746382 .9847485018019042 + .9928504144598651 .11936521481099137 + .617647307937804 .7864552135990858 + .8715950866559511 .49022648328829116 + .2696683255729151 .9629532668736839 + .9504860739494817 .3107671527496115 + .4523495872337709 .8918407093923427 + .7592091889783881 .6508466849963809 + .07662386139203149 .997060070339483 + .9975114561403035 .07050457338961387 + .6554928529996153 .7552013768965365 + .8945994856313827 .4468688401623742 + .31659337555616585 .9485613499157303 + .9645897932898128 .2637546789748314 + .49556526182577254 .8685707059713409 + .79023022143731 .6128100824294097 + .12545498341154623 .9920993131421918 + .9857975091675675 .16793829497473117 + .5783137964116556 .8158144108067338 + .8464909387740521 .532403127877198 + .22209362097320354 .9750253450669941 + .9340925504042589 .35703096123343003 + .4080441628649787 .9129621904283982 + .726359155084346 .6873153408917592 + .027608145778965743 .9996188224951786 + .9989412931868569 .04600318213091463 + .673829000378756 .7388873244606151 + .9052967593181188 .4247796812091088 + .33977688440682685 .9405060705932683 + .9707721407289504 .2400030224487415 + .5167317990176499 .8561473283751945 + .8050313311429635 .5932322950397998 + .1497645346773215 .9887216919603238 + .9896220174632009 .14369503315029444 + .5981607069963423 .8013761717231402 + .8593018183570084 .5114688504379704 + .24595505033579462 .9692812353565485 + .9425731976014469 .3339996514420094 + .4303264813400826 .9026733182372588 + .7430079521351217 .6692825883466361 + .052131704680283324 .9986402181802653 + .9954807554919269 .094963495329639 + .6367618612362842 .7710605242618138 + .8833633386657316 .46868882203582796 + .29321916269425863 .9560452513499964 + .9578264130275329 .2873474595447295 + .47410021465055 .8804708890521608 + .7749531065948739 .6320187359398091 + .10106986275482782 .9948793307948056 + .9813791933137546 .19208039704989244 + .5581185312205561 .829761233794523 + .8331701647019132 .5530167055800276 + .1980984107179536 .9801821359681174 + .9250492407826776 .37984720892405116 + .38551605384391885 .9227011283338785 + .7092728264388657 .7049340803759049 + .003067956762965976 .9999952938095762 + ))) + +(define med-lut + (list->f64vector '(1. 0. + .9999999999820472 5.9921124526424275e-6 + .9999999999281892 1.1984224905069707e-5 + .9999999998384257 1.7976337357066685e-5 + .9999999997127567 2.396844980841822e-5 + .9999999995511824 2.9960562258909154e-5 + .9999999993537025 3.5952674708324344e-5 + .9999999991203175 4.1944787156448635e-5 + .9999999988510269 4.793689960306688e-5 + .9999999985458309 5.3929012047963936e-5 + .9999999982047294 5.992112449092465e-5 + .9999999978277226 6.591323693173387e-5 + .9999999974148104 7.190534937017645e-5 + .9999999969659927 7.789746180603723e-5 + .9999999964812697 8.388957423910108e-5 + .9999999959606412 8.988168666915283e-5 + .9999999954041073 9.587379909597734e-5 + .999999994811668 1.0186591151935948e-4 + .9999999941833233 1.0785802393908407e-4 + .9999999935190732 1.1385013635493597e-4 + .9999999928189177 1.1984224876670004e-4 + .9999999920828567 1.2583436117416112e-4 + .9999999913108903 1.3182647357710405e-4 + .9999999905030187 1.3781858597531374e-4 + .9999999896592414 1.4381069836857496e-4 + .9999999887795589 1.498028107566726e-4 + .9999999878639709 1.5579492313939151e-4 + .9999999869124775 1.6178703551651655e-4 + .9999999859250787 1.6777914788783258e-4 + .9999999849017744 1.737712602531244e-4 + .9999999838425648 1.797633726121769e-4 + .9999999827474497 1.8575548496477492e-4 + .9999999816164293 1.9174759731070332e-4 + .9999999804495034 1.9773970964974692e-4 + .9999999792466722 2.037318219816906e-4 + .9999999780079355 2.0972393430631923e-4 + .9999999767332933 2.1571604662341763e-4 + .9999999754227459 2.2170815893277063e-4 + .9999999740762929 2.2770027123416315e-4 + .9999999726939346 2.3369238352737996e-4 + .9999999712756709 2.3968449581220595e-4 + .9999999698215016 2.45676608088426e-4 + .9999999683314271 2.5166872035582493e-4 + .9999999668054471 2.5766083261418755e-4 + .9999999652435617 2.636529448632988e-4 + .9999999636457709 2.696450571029434e-4 + .9999999620120748 2.756371693329064e-4 + .9999999603424731 2.8162928155297243e-4 + .9999999586369661 2.876213937629265e-4 + .9999999568955537 2.936135059625534e-4 + .9999999551182358 2.99605618151638e-4 + .9999999533050126 3.055977303299651e-4 + .9999999514558838 3.115898424973196e-4 + .9999999495708498 3.1758195465348636e-4 + .9999999476499103 3.235740667982502e-4 + .9999999456930654 3.2956617893139595e-4 + .9999999437003151 3.3555829105270853e-4 + .9999999416716594 3.4155040316197275e-4 + .9999999396070982 3.475425152589734e-4 + .9999999375066316 3.535346273434955e-4 + .9999999353702598 3.595267394153237e-4 + .9999999331979824 3.6551885147424295e-4 + .9999999309897996 3.7151096352003814e-4 + .9999999287457114 3.7750307555249406e-4 + .9999999264657179 3.8349518757139556e-4 + .9999999241498189 3.8948729957652753e-4 + .9999999217980144 3.954794115676748e-4 + .9999999194103046 4.0147152354462224e-4 + .9999999169866894 4.0746363550715466e-4 + .9999999145271687 4.134557474550569e-4 + .9999999120317428 4.194478593881139e-4 + .9999999095004113 4.2543997130611036e-4 + .9999999069331744 4.314320832088313e-4 + .9999999043300322 4.3742419509606144e-4 + .9999999016909845 4.4341630696758576e-4 + .9999998990160315 4.4940841882318896e-4 + .9999998963051729 4.55400530662656e-4 + .999999893558409 4.613926424857717e-4 + .9999998907757398 4.673847542923209e-4 + .9999998879571651 4.7337686608208844e-4 + .9999998851026849 4.793689778548592e-4 + .9999998822122994 4.8536108961041806e-4 + .9999998792860085 4.913532013485497e-4 + .9999998763238122 4.973453130690393e-4 + .9999998733257104 5.033374247716714e-4 + .9999998702917032 5.09329536456231e-4 + .9999998672217907 5.153216481225028e-4 + .9999998641159727 5.213137597702719e-4 + .9999998609742493 5.27305871399323e-4 + .9999998577966206 5.332979830094408e-4 + .9999998545830864 5.392900946004105e-4 + .9999998513336468 5.452822061720168e-4 + .9999998480483018 5.512743177240444e-4 + .9999998447270514 5.572664292562783e-4 + .9999998413698955 5.632585407685033e-4 + .9999998379768343 5.692506522605043e-4 + .9999998345478677 5.752427637320661e-4 + .9999998310829956 5.812348751829735e-4 + .9999998275822183 5.872269866130116e-4 + .9999998240455354 5.93219098021965e-4 + .9999998204729471 5.992112094096185e-4 + .9999998168644535 6.052033207757572e-4 + .9999998132200545 6.111954321201659e-4 + .99999980953975 6.171875434426292e-4 + .9999998058235401 6.231796547429323e-4 + .9999998020714248 6.291717660208597e-4 + .9999997982834041 6.351638772761965e-4 + .9999997944594781 6.411559885087275e-4 + .9999997905996466 6.471480997182375e-4 + .9999997867039097 6.531402109045114e-4 + .9999997827722674 6.591323220673341e-4 + .9999997788047197 6.651244332064902e-4 + .9999997748012666 6.711165443217649e-4 + .9999997707619082 6.771086554129428e-4 + .9999997666866443 6.83100766479809e-4 + .9999997625754748 6.89092877522148e-4 + .9999997584284002 6.950849885397449e-4 + .9999997542454201 7.010770995323844e-4 + .9999997500265345 7.070692104998515e-4 + .9999997457717437 7.130613214419311e-4 + .9999997414810473 7.190534323584079e-4 + .9999997371544456 7.250455432490666e-4 + .9999997327919384 7.310376541136925e-4 + .9999997283935259 7.3702976495207e-4 + .999999723959208 7.430218757639842e-4 + .9999997194889846 7.490139865492199e-4 + .9999997149828559 7.55006097307562e-4 + .9999997104408218 7.609982080387952e-4 + .9999997058628822 7.669903187427045e-4 + .9999997012490373 7.729824294190747e-4 + .9999996965992869 7.789745400676906e-4 + .9999996919136313 7.849666506883372e-4 + .99999968719207 7.909587612807992e-4 + .9999996824346035 7.969508718448614e-4 + .9999996776412315 8.029429823803089e-4 + .9999996728119542 8.089350928869263e-4 + .9999996679467715 8.149272033644986e-4 + .9999996630456833 8.209193138128106e-4 + .9999996581086897 8.269114242316472e-4 + .9999996531357909 8.329035346207931e-4 + .9999996481269865 8.388956449800333e-4 + .9999996430822767 8.448877553091527e-4 + .9999996380016616 8.508798656079359e-4 + .999999632885141 8.56871975876168e-4 + .9999996277327151 8.628640861136338e-4 + .9999996225443838 8.68856196320118e-4 + .9999996173201471 8.748483064954056e-4 + .999999612060005 8.808404166392814e-4 + .9999996067639574 8.868325267515304e-4 + .9999996014320045 8.928246368319371e-4 + .9999995960641462 8.988167468802867e-4 + .9999995906603825 9.048088568963639e-4 + .9999995852207133 9.108009668799535e-4 + .9999995797451389 9.167930768308405e-4 + .9999995742336589 9.227851867488095e-4 + .9999995686862736 9.287772966336457e-4 + .9999995631029829 9.347694064851338e-4 + .9999995574837868 9.407615163030585e-4 + .9999995518286853 9.467536260872047e-4 + .9999995461376784 9.527457358373575e-4 + .9999995404107661 9.587378455533015e-4 + .9999995346479484 9.647299552348216e-4 + .9999995288492254 9.707220648817027e-4 + .9999995230145969 9.767141744937296e-4 + .9999995171440631 9.827062840706872e-4 + .9999995112376238 9.886983936123602e-4 + .9999995052952791 9.946905031185337e-4 + .9999994993170291 .0010006826125889925 + .9999994933028736 .0010066747220235214 + .9999994872528128 .001012666831421905 + .9999994811668466 .0010186589407839286 + .999999475044975 .0010246510501093766 + .9999994688871979 .0010306431593980344 + .9999994626935156 .0010366352686496862 + .9999994564639277 .0010426273778641173 + .9999994501984345 .0010486194870411127 + .999999443897036 .0010546115961804568 + .999999437559732 .0010606037052819344 + .9999994311865227 .0010665958143453308 + .9999994247774079 .0010725879233704307 + .9999994183323877 .0010785800323570187 + .9999994118514622 .0010845721413048801 + .9999994053346313 .0010905642502137994 + .9999993987818949 .0010965563590835613 + .9999993921932533 .0011025484679139511 + .9999993855687062 .0011085405767047535 + .9999993789082536 .0011145326854557532 + .9999993722118957 .001120524794166735 + .9999993654796325 .0011265169028374842 + .9999993587114638 .0011325090114677853 + .9999993519073898 .001138501120057423 + .9999993450674104 .0011444932286061825 + .9999993381915255 .0011504853371138485 + .9999993312797354 .0011564774455802057 + .9999993243320398 .0011624695540050393 + .9999993173484387 .001168461662388134 + .9999993103289324 .0011744537707292742 + .9999993032735206 .0011804458790282454 + .9999992961822035 .0011864379872848323 + .9999992890549809 .0011924300954988195 + .999999281891853 .001198422203669992 + .9999992746928197 .0012044143117981348 + .999999267457881 .0012104064198830327 + .999999260187037 .0012163985279244702 + .9999992528802875 .0012223906359222325 + .9999992455376326 .0012283827438761045 + .9999992381590724 .0012343748517858707 + .9999992307446068 .0012403669596513162 + .9999992232942359 .001246359067472226 + .9999992158079595 .0012523511752483847 + .9999992082857777 .001258343282979577 + .9999992007276906 .001264335390665588 + .999999193133698 .0012703274983062026 + .9999991855038001 .0012763196059012057 + .9999991778379967 .001282311713450382 + .9999991701362881 .0012883038209535163 + .999999162398674 .0012942959284103935 + .9999991546251547 .0013002880358207985 + .9999991468157298 .001306280143184516 + .9999991389703996 .001312272250501331 + .999999131089164 .0013182643577710285 + .999999123172023 .0013242564649933932 + .9999991152189767 .0013302485721682098 + .9999991072300249 .001336240679295263 + .9999990992051678 .0013422327863743383 + .9999990911444054 .0013482248934052201 + .9999990830477375 .0013542170003876934 + .9999990749151643 .001360209107321543 + .9999990667466857 .0013662012142065536 + .9999990585423016 .0013721933210425101 + .9999990503020123 .0013781854278291975 + .9999990420258176 .0013841775345664006 + .9999990337137175 .0013901696412539043 + .999999025365712 .0013961617478914935 + .999999016981801 .0014021538544789526 + .9999990085619848 .001408145961016067 + .9999990001062631 .0014141380675026214 + .9999989916146361 .0014201301739384005 + .9999989830871038 .0014261222803231893 + .9999989745236659 .0014321143866567725 + .9999989659243228 .001438106492938935 + .9999989572890743 .0014440985991694619 + .9999989486179204 .0014500907053481378 + .9999989399108612 .0014560828114747475 + .9999989311678965 .0014620749175490758 + .9999989223890265 .001468067023570908 + .9999989135742512 .0014740591295400284 + .9999989047235704 .0014800512354562223 + .9999988958369843 .0014860433413192743 + .9999988869144928 .0014920354471289693 + .9999988779560959 .0014980275528850922 + .9999988689617937 .0015040196585874275 + .9999988599315861 .0015100117642357607 + .999998850865473 .0015160038698298762 + .9999988417634548 .001521995975369559 + .999998832625531 .0015279880808545937 + .9999988234517019 .0015339801862847657 + .9999988142419675 .0015399722916598592 + .9999988049963277 .0015459643969796596 + .9999987957147825 .0015519565022439512 + .9999987863973319 .0015579486074525195 + .9999987770439759 .001563940712605149 + .9999987676547146 .0015699328177016243 + .999998758229548 .0015759249227417307 + .9999987487684759 .0015819170277252528 + .9999987392714985 .0015879091326519755 + .9999987297386157 .0015939012375216837 + .9999987201698276 .0015998933423341623 + .9999987105651341 .001605885447089196 + .9999987009245352 .0016118775517865696 + .999998691248031 .0016178696564260683 + .9999986815356214 .0016238617610074765 + .9999986717873064 .0016298538655305794 + .9999986620030861 .0016358459699951618 + .9999986521829605 .0016418380744010084 + .9999986423269294 .0016478301787479041 + .999998632434993 .0016538222830356339 + .9999986225071512 .0016598143872639823 + .999998612543404 .0016658064914327345 + .9999986025437515 .0016717985955416754 + .9999985925081937 .0016777906995905894 + .9999985824367305 .0016837828035792617 + .9999985723293618 .0016897749075074774 + .999998562186088 .0016957670113750207 + .9999985520069086 .0017017591151816769 + .9999985417918239 .0017077512189272307 + .999998531540834 .001713743322611467 + .9999985212539385 .0017197354262341706 + .9999985109311378 .0017257275297951264 + .9999985005724317 .0017317196332941192 + .9999984901778203 .0017377117367309341 + .9999984797473034 .0017437038401053556 + .9999984692808812 .0017496959434171687 + .9999984587785538 .0017556880466661582 + .9999984482403208 .001761680149852109 + .9999984376661826 .0017676722529748061 + .999998427056139 .0017736643560340342 + .99999841641019 .001779656459029578 + .9999984057283358 .0017856485619612225 + .9999983950105761 .0017916406648287528 + .999998384256911 .0017976327676319532 + .9999983734673407 .001803624870370609 + .9999983626418649 .0018096169730445048 + .9999983517804839 .0018156090756534257 + .9999983408831975 .0018216011781971562 + .9999983299500057 .0018275932806754815 + .9999983189809085 .0018335853830881864 + .999998307975906 .0018395774854350557 + .9999982969349982 .001845569587715874 + .9999982858581851 .0018515616899304264 + .9999982747454665 .001857553792078498 + .9999982635968426 .001863545894159873 + .9999982524123134 .0018695379961743367 + .9999982411918789 .001875530098121674 + .9999982299355389 .0018815222000016696 + .9999982186432936 .0018875143018141083 + .999998207315143 .0018935064035587748 + .999998195951087 .0018994985052354545 + .9999981845511257 .0019054906068439318 + .9999981731152591 .0019114827083839918 + .999998161643487 .001917474809855419 + .9999981501358096 .0019234669112579987 + .999998138592227 .0019294590125915154 + .9999981270127389 .0019354511138557542 + .9999981153973455 .0019414432150504997 + .9999981037460468 .0019474353161755369 + .9999980920588427 .001953427417230651 + .9999980803357332 .001959419518215626 + .9999980685767185 .0019654116191302473 + .9999980567817984 .0019714037199743 + .9999980449509729 .0019773958207475683 + .9999980330842422 .0019833879214498375 + .999998021181606 .001989380022080892 + .9999980092430646 .0019953721226405176 + .9999979972686177 .002001364223128498 + .9999979852582656 .002007356323544619 + .9999979732120081 .002013348423888665 + .9999979611298453 .002019340524160421 + .9999979490117771 .0020253326243596715 + .9999979368578036 .0020313247244862017 + .9999979246679247 .002037316824539796 + .9999979124421405 .00204330892452024 + .999997900180451 .002049301024427318 + .9999978878828562 .0020552931242608153 + .9999978755493559 .002061285224020516 + .9999978631799504 .0020672773237062057 + .9999978507746395 .002073269423317669 + .9999978383334234 .0020792615228546903 + .9999978258563018 .002085253622317055 + .999997813343275 .0020912457217045484 + .9999978007943428 .002097237821016954 + .9999977882095052 .0021032299202540577 + .9999977755887623 .0021092220194156444 + .9999977629321142 .0021152141185014984 + .9999977502395607 .0021212062175114043 + .9999977375111019 .002127198316445148 + .9999977247467376 .0021331904153025134 + .9999977119464681 .002139182514083286 + .9999976991102932 .0021451746127872503 + .9999976862382131 .002151166711414191 + .9999976733302276 .0021571588099638934 + .9999976603863368 .0021631509084361423 + .9999976474065406 .002169143006830722 + .9999976343908391 .002175135105147418 + .9999976213392323 .0021811272033860148 + .9999976082517201 .002187119301546297 + .9999975951283027 .00219311139962805 + .9999975819689799 .0021991034976310588 + .9999975687737518 .0022050955955551076 + .9999975555426184 .0022110876933999816 + .9999975422755796 .0022170797911654654 + .9999975289726355 .002223071888851344 + .9999975156337861 .0022290639864574026 + .9999975022590314 .0022350560839834253 + .9999974888483714 .002241048181429198 + .999997475401806 .0022470402787945045 + .9999974619193353 .00225303237607913 + .9999974484009593 .0022590244732828596 + .9999974348466779 .0022650165704054784 + .9999974212564913 .0022710086674467703 + .9999974076303992 .002277000764406521 + .9999973939684019 .002282992861284515 + .9999973802704993 .0022889849580805368 + .9999973665366915 .0022949770547943723 + .9999973527669782 .0023009691514258054 + .9999973389613596 .002306961247974621 + .9999973251198357 .0023129533444406045 + .9999973112424065 .0023189454408235406 + .999997297329072 .0023249375371232135 + .9999972833798322 .002330929633339409 + .999997269394687 .0023369217294719113 + .9999972553736366 .0023429138255205055 + .9999972413166809 .0023489059214849765 + .9999972272238198 .002354898017365109 + .9999972130950534 .0023608901131606883 + .9999971989303816 .0023668822088714985 + .9999971847298047 .0023728743044973246 + .9999971704933224 .0023788664000379523 + .9999971562209347 .0023848584954931653 + .9999971419126418 .0023908505908627493 + .9999971275684435 .0023968426861464883 + .99999711318834 .002402834781344168 + .9999970987723311 .0024088268764555732 + .9999970843204169 .002414818971480488 + .9999970698325974 .002420811066418698 + .9999970553088726 .0024268031612699878 + .9999970407492426 .002432795256034142 + .9999970261537071 .002438787350710946 + .9999970115222664 .002444779445300184 + .9999969968549204 .0024507715398016418 + .9999969821516691 .002456763634215103 + .9999969674125124 .002462755728540353 + .9999969526374506 .0024687478227771774 + .9999969378264834 .00247473991692536 + .9999969229796108 .002480732010984686 + .999996908096833 .0024867241049549406 + .9999968931781499 .002492716198835908 + .9999968782235614 .0024987082926273734 + .9999968632330677 .002504700386329122 + .9999968482066687 .002510692479940938 + .9999968331443644 .0025166845734626068 + .9999968180461547 .0025226766668939127 + .9999968029120399 .002528668760234641 + .9999967877420196 .002534660853484576 + .9999967725360941 .0025406529466435036 + .9999967572942633 .002546645039711208 + .9999967420165272 .002552637132687474 + .9999967267028858 .002558629225572086 + .9999967113533391 .0025646213183648297 + .9999966959678871 .0025706134110654896 + .9999966805465298 .002576605503673851 + .9999966650892672 .0025825975961896977 + .9999966495960994 .0025885896886128153 + .9999966340670262 .0025945817809429885 + .9999966185020478 .0026005738731800024 + .9999966029011641 .0026065659653236417 + .999996587264375 .002612558057373691 + .9999965715916808 .002618550149329935 + .9999965558830811 .0026245422411921592 + .9999965401385762 .002630534332960148 + .9999965243581661 .002636526424633687 + .9999965085418506 .0026425185162125596 + .9999964926896299 .0026485106076965517 + .9999964768015038 .0026545026990854484 + .9999964608774725 .0026604947903790337 + .9999964449175359 .0026664868815770926 + .999996428921694 .0026724789726794104 + .9999964128899468 .002678471063685772 + .9999963968222944 .0026844631545959617 + .9999963807187366 .002690455245409765 + .9999963645792737 .002696447336126966 + .9999963484039053 .00270243942674735 + .9999963321926317 .002708431517270702 + .9999963159454529 .0027144236076968066 + .9999962996623687 .0027204156980254485 + .9999962833433793 .002726407788256413 + .9999962669884847 .002732399878389485 + .9999962505976846 .0027383919684244484 + .9999962341709794 .002744384058361089 + .9999962177083689 .0027503761481991913 + .999996201209853 .0027563682379385403 + .9999961846754319 .0027623603275789207 + .9999961681051056 .0027683524171201175 + .999996151498874 .002774344506561915 + .9999961348567371 .002780336595904099 + .9999961181786949 .0027863286851464537 + .9999961014647475 .0027923207742887642 + .9999960847148948 .0027983128633308155 + .9999960679291368 .002804304952272392 + .9999960511074735 .002810297041113279 + .9999960342499049 .0028162891298532606 + .9999960173564312 .0028222812184921227 + .9999960004270521 .002828273307029649 + .9999959834617678 .002834265395465626 + .9999959664605781 .0028402574837998367 + .9999959494234832 .002846249572032067 + .9999959323504831 .0028522416601621014 + .9999959152415777 .002858233748189725 + .999995898096767 .002864225836114723 + .9999958809160512 .0028702179239368793 + .9999958636994299 .0028762100116559793 + .9999958464469034 .0028822020992718077 + .9999958291584717 .0028881941867841495 + .9999958118341348 .0028941862741927895 + .9999957944738925 .0029001783614975127 + .999995777077745 .002906170448698104 + .9999957596456922 .0029121625357943475 + .9999957421777342 .002918154622786029 + .999995724673871 .0029241467096729327 + .9999957071341024 .002930138796454844 + .9999956895584287 .0029361308831315474 + .9999956719468496 .0029421229697028273 + .9999956542993652 .0029481150561684695 + .9999956366159757 .0029541071425282584 + .9999956188966809 .002960099228781979 + .9999956011414808 .002966091314929416 + .9999955833503754 .002972083400970354 + .9999955655233649 .0029780754869045785 + .9999955476604491 .0029840675727318736 + .999995529761628 .002990059658452025 + .9999955118269016 .0029960517440648163 + .99999549385627 .0030020438295700336 + .9999954758497331 .0030080359149674612 + .999995457807291 .003014028000256884 + .9999954397289438 .003020020085438087 + .9999954216146911 .0030260121705108552 + .9999954034645333 .003032004255474973 + .9999953852784702 .003037996340330225 + .9999953670565019 .003043988425076397 + .9999953487986284 .003049980509713273 + .9999953305048496 .0030559725942406386 + .9999953121751655 .003061964678658278 + ))) + + +(define high-lut + (list->f64vector '(1. 0. + .9999999999999999 1.1703344634137277e-8 + .9999999999999998 2.3406689268274554e-8 + .9999999999999993 3.5110033902411824e-8 + .9999999999999989 4.6813378536549095e-8 + .9999999999999983 5.851672317068635e-8 + .9999999999999976 7.022006780482361e-8 + .9999999999999967 8.192341243896085e-8 + .9999999999999957 9.362675707309808e-8 + .9999999999999944 1.0533010170723531e-7 + .9999999999999931 1.170334463413725e-7 + .9999999999999917 1.287367909755097e-7 + .9999999999999901 1.4044013560964687e-7 + .9999999999999885 1.5214348024378403e-7 + .9999999999999866 1.6384682487792116e-7 + .9999999999999846 1.7555016951205827e-7 + .9999999999999825 1.8725351414619535e-7 + .9999999999999802 1.989568587803324e-7 + .9999999999999778 2.1066020341446942e-7 + .9999999999999752 2.2236354804860645e-7 + .9999999999999726 2.3406689268274342e-7 + .9999999999999698 2.4577023731688034e-7 + .9999999999999668 2.5747358195101726e-7 + .9999999999999638 2.6917692658515413e-7 + .9999999999999606 2.8088027121929094e-7 + .9999999999999571 2.9258361585342776e-7 + .9999999999999537 3.042869604875645e-7 + .99999999999995 3.159903051217012e-7 + .9999999999999463 3.276936497558379e-7 + .9999999999999424 3.3939699438997453e-7 + .9999999999999384 3.5110033902411114e-7 + .9999999999999342 3.6280368365824763e-7 + .9999999999999298 3.7450702829238413e-7 + .9999999999999254 3.8621037292652057e-7 + .9999999999999208 3.979137175606569e-7 + .9999999999999161 4.0961706219479325e-7 + .9999999999999113 4.2132040682892953e-7 + .9999999999999063 4.330237514630657e-7 + .9999999999999011 4.447270960972019e-7 + .9999999999998959 4.5643044073133796e-7 + .9999999999998904 4.68133785365474e-7 + .9999999999998849 4.7983712999961e-7 + .9999999999998792 4.915404746337459e-7 + .9999999999998733 5.032438192678817e-7 + .9999999999998674 5.149471639020175e-7 + .9999999999998613 5.266505085361531e-7 + .9999999999998551 5.383538531702888e-7 + .9999999999998487 5.500571978044243e-7 + .9999999999998422 5.617605424385598e-7 + .9999999999998356 5.734638870726952e-7 + .9999999999998288 5.851672317068305e-7 + .9999999999998219 5.968705763409657e-7 + .9999999999998148 6.085739209751009e-7 + .9999999999998076 6.202772656092359e-7 + .9999999999998003 6.319806102433709e-7 + .9999999999997928 6.436839548775058e-7 + .9999999999997853 6.553872995116406e-7 + .9999999999997775 6.670906441457753e-7 + .9999999999997696 6.7879398877991e-7 + .9999999999997616 6.904973334140445e-7 + .9999999999997534 7.02200678048179e-7 + .9999999999997452 7.139040226823132e-7 + .9999999999997368 7.256073673164475e-7 + .9999999999997282 7.373107119505817e-7 + .9999999999997194 7.490140565847157e-7 + .9999999999997107 7.607174012188497e-7 + .9999999999997017 7.724207458529835e-7 + .9999999999996926 7.841240904871172e-7 + .9999999999996834 7.958274351212508e-7 + .9999999999996739 8.075307797553844e-7 + .9999999999996644 8.192341243895178e-7 + .9999999999996547 8.309374690236511e-7 + .999999999999645 8.426408136577842e-7 + .9999999999996351 8.543441582919173e-7 + .999999999999625 8.660475029260503e-7 + .9999999999996148 8.777508475601831e-7 + .9999999999996044 8.894541921943158e-7 + .999999999999594 9.011575368284484e-7 + .9999999999995833 9.128608814625808e-7 + .9999999999995726 9.245642260967132e-7 + .9999999999995617 9.362675707308454e-7 + .9999999999995507 9.479709153649775e-7 + .9999999999995395 9.596742599991095e-7 + .9999999999995283 9.713776046332412e-7 + .9999999999995168 9.83080949267373e-7 + .9999999999995052 9.947842939015044e-7 + .9999999999994935 1.006487638535636e-6 + .9999999999994816 1.0181909831697673e-6 + .9999999999994696 1.0298943278038984e-6 + .9999999999994575 1.0415976724380293e-6 + .9999999999994453 1.0533010170721601e-6 + .9999999999994329 1.065004361706291e-6 + .9999999999994204 1.0767077063404215e-6 + .9999999999994077 1.088411050974552e-6 + .9999999999993949 1.1001143956086822e-6 + .9999999999993819 1.1118177402428122e-6 + .9999999999993688 1.1235210848769423e-6 + .9999999999993556 1.135224429511072e-6 + .9999999999993423 1.1469277741452017e-6 + .9999999999993288 1.1586311187793313e-6 + .9999999999993151 1.1703344634134605e-6 + .9999999999993014 1.1820378080475897e-6 + .9999999999992875 1.1937411526817187e-6 + .9999999999992735 1.2054444973158477e-6 + .9999999999992593 1.2171478419499764e-6 + .9999999999992449 1.2288511865841048e-6 + .9999999999992305 1.2405545312182331e-6 + .999999999999216 1.2522578758523615e-6 + .9999999999992012 1.2639612204864894e-6 + .9999999999991863 1.2756645651206173e-6 + .9999999999991713 1.287367909754745e-6 + .9999999999991562 1.2990712543888725e-6 + .9999999999991409 1.3107745990229998e-6 + .9999999999991255 1.3224779436571269e-6 + .9999999999991099 1.3341812882912537e-6 + .9999999999990943 1.3458846329253806e-6 + .9999999999990785 1.3575879775595072e-6 + .9999999999990625 1.3692913221936337e-6 + .9999999999990464 1.3809946668277597e-6 + .9999999999990302 1.3926980114618857e-6 + .9999999999990138 1.4044013560960117e-6 + .9999999999989974 1.4161047007301373e-6 + .9999999999989807 1.4278080453642627e-6 + .9999999999989639 1.439511389998388e-6 + .999999999998947 1.451214734632513e-6 + .99999999999893 1.462918079266638e-6 + .9999999999989128 1.4746214239007625e-6 + .9999999999988954 1.486324768534887e-6 + .999999999998878 1.4980281131690111e-6 + .9999999999988604 1.5097314578031353e-6 + .9999999999988426 1.5214348024372591e-6 + .9999999999988247 1.5331381470713828e-6 + .9999999999988067 1.544841491705506e-6 + .9999999999987886 1.5565448363396294e-6 + .9999999999987703 1.5682481809737524e-6 + .9999999999987519 1.579951525607875e-6 + .9999999999987333 1.5916548702419977e-6 + .9999999999987146 1.60335821487612e-6 + .9999999999986958 1.615061559510242e-6 + .9999999999986768 1.626764904144364e-6 + .9999999999986577 1.6384682487784858e-6 + .9999999999986384 1.6501715934126072e-6 + .9999999999986191 1.6618749380467283e-6 + .9999999999985996 1.6735782826808495e-6 + .9999999999985799 1.6852816273149702e-6 + .9999999999985602 1.6969849719490907e-6 + .9999999999985402 1.708688316583211e-6 + .9999999999985201 1.720391661217331e-6 + .9999999999985 1.732095005851451e-6 + .9999999999984795 1.7437983504855706e-6 + .9999999999984591 1.7555016951196899e-6 + .9999999999984385 1.767205039753809e-6 + .9999999999984177 1.778908384387928e-6 + .9999999999983968 1.7906117290220465e-6 + .9999999999983759 1.802315073656165e-6 + .9999999999983546 1.814018418290283e-6 + .9999999999983333 1.825721762924401e-6 + .9999999999983119 1.8374251075585186e-6 + .9999999999982904 1.8491284521926361e-6 + .9999999999982686 1.8608317968267533e-6 + .9999999999982468 1.8725351414608702e-6 + .9999999999982249 1.8842384860949866e-6 + .9999999999982027 1.8959418307291031e-6 + .9999999999981805 1.9076451753632194e-6 + .999999999998158 1.919348519997335e-6 + .9999999999981355 1.9310518646314507e-6 + .9999999999981128 1.942755209265566e-6 + .9999999999980901 1.954458553899681e-6 + .9999999999980671 1.966161898533796e-6 + .999999999998044 1.9778652431679103e-6 + .9999999999980208 1.9895685878020246e-6 + .9999999999979975 2.0012719324361386e-6 + .999999999997974 2.012975277070252e-6 + .9999999999979503 2.0246786217043656e-6 + .9999999999979265 2.0363819663384787e-6 + .9999999999979027 2.048085310972592e-6 + .9999999999978786 2.0597886556067045e-6 + .9999999999978545 2.0714920002408167e-6 + .9999999999978302 2.0831953448749286e-6 + .9999999999978058 2.0948986895090404e-6 + .9999999999977811 2.106602034143152e-6 + .9999999999977564 2.118305378777263e-6 + .9999999999977315 2.1300087234113738e-6 + .9999999999977065 2.1417120680454843e-6 + .9999999999976814 2.153415412679595e-6 + .9999999999976561 2.1651187573137046e-6 + .9999999999976307 2.1768221019478143e-6 + .9999999999976051 2.188525446581924e-6 + .9999999999975795 2.200228791216033e-6 + .9999999999975536 2.2119321358501417e-6 + .9999999999975278 2.22363548048425e-6 + .9999999999975017 2.2353388251183586e-6 + .9999999999974754 2.247042169752466e-6 + .999999999997449 2.2587455143865738e-6 + .9999999999974225 2.2704488590206814e-6 + .9999999999973959 2.282152203654788e-6 + .9999999999973691 2.293855548288895e-6 + .9999999999973422 2.305558892923001e-6 + .9999999999973151 2.317262237557107e-6 + .999999999997288 2.328965582191213e-6 + .9999999999972606 2.340668926825318e-6 + .9999999999972332 2.352372271459423e-6 + .9999999999972056 2.364075616093528e-6 + .9999999999971778 2.3757789607276323e-6 + .99999999999715 2.3874823053617365e-6 + .999999999997122 2.3991856499958403e-6 + .9999999999970938 2.4108889946299437e-6 + .9999999999970656 2.4225923392640466e-6 + .9999999999970371 2.4342956838981495e-6 + .9999999999970085 2.445999028532252e-6 + .9999999999969799 2.457702373166354e-6 + .999999999996951 2.4694057178004558e-6 + .999999999996922 2.4811090624345574e-6 + .9999999999968929 2.4928124070686583e-6 + .9999999999968637 2.504515751702759e-6 + .9999999999968343 2.5162190963368595e-6 + .9999999999968048 2.5279224409709594e-6 + .9999999999967751 2.5396257856050594e-6 + .9999999999967454 2.5513291302391585e-6 + .9999999999967154 2.5630324748732576e-6 + .9999999999966853 2.5747358195073563e-6 + .9999999999966551 2.5864391641414546e-6 + .9999999999966248 2.5981425087755525e-6 + .9999999999965944 2.6098458534096503e-6 + .9999999999965637 2.6215491980437473e-6 + .999999999996533 2.6332525426778443e-6 + .9999999999965021 2.644955887311941e-6 + .999999999996471 2.656659231946037e-6 + .99999999999644 2.6683625765801328e-6 + .9999999999964087 2.680065921214228e-6 + .9999999999963772 2.6917692658483234e-6 + .9999999999963456 2.703472610482418e-6 + .999999999996314 2.7151759551165123e-6 + .9999999999962821 2.7268792997506064e-6 + .9999999999962501 2.7385826443846996e-6 + .9999999999962179 2.750285989018793e-6 + .9999999999961857 2.761989333652886e-6 + .9999999999961533 2.7736926782869783e-6 + .9999999999961208 2.78539602292107e-6 + .9999999999960881 2.797099367555162e-6 + .9999999999960553 2.808802712189253e-6 + .9999999999960224 2.8205060568233443e-6 + .9999999999959893 2.832209401457435e-6 + .9999999999959561 2.8439127460915247e-6 + .9999999999959227 2.8556160907256145e-6 + .9999999999958893 2.867319435359704e-6 + .9999999999958556 2.879022779993793e-6 + .9999999999958219 2.8907261246278814e-6 + .9999999999957879 2.90242946926197e-6 + .999999999995754 2.9141328138960576e-6 + .9999999999957198 2.925836158530145e-6 + .9999999999956855 2.9375395031642317e-6 + .999999999995651 2.9492428477983186e-6 + .9999999999956164 2.9609461924324046e-6 + .9999999999955816 2.9726495370664905e-6 + .9999999999955468 2.9843528817005757e-6 + .9999999999955118 2.996056226334661e-6 + .9999999999954767 3.007759570968745e-6 + .9999999999954414 3.0194629156028294e-6 + .999999999995406 3.0311662602369133e-6 + .9999999999953705 3.0428696048709963e-6 + .9999999999953348 3.0545729495050794e-6 + .999999999995299 3.066276294139162e-6 + .999999999995263 3.0779796387732437e-6 + .9999999999952269 3.0896829834073255e-6 + .9999999999951907 3.101386328041407e-6 + .9999999999951543 3.1130896726754873e-6 + .9999999999951178 3.1247930173095678e-6 + .9999999999950812 3.136496361943648e-6 + .9999999999950444 3.148199706577727e-6 + .9999999999950075 3.1599030512118063e-6 + .9999999999949705 3.171606395845885e-6 + .9999999999949333 3.183309740479963e-6 + .999999999994896 3.195013085114041e-6 + .9999999999948584 3.206716429748118e-6 + .9999999999948209 3.218419774382195e-6 + .9999999999947832 3.2301231190162714e-6 + .9999999999947453 3.2418264636503477e-6 + .9999999999947072 3.253529808284423e-6 + .9999999999946692 3.265233152918498e-6 + .9999999999946309 3.276936497552573e-6 + .9999999999945924 3.288639842186647e-6 + .9999999999945539 3.300343186820721e-6 + .9999999999945152 3.312046531454794e-6 + .9999999999944763 3.323749876088867e-6 + .9999999999944373 3.3354532207229395e-6 + .9999999999943983 3.3471565653570115e-6 + .9999999999943591 3.358859909991083e-6 + .9999999999943197 3.370563254625154e-6 + .9999999999942801 3.3822665992592245e-6 + .9999999999942405 3.3939699438932944e-6 + .9999999999942008 3.4056732885273643e-6 + .9999999999941608 3.4173766331614334e-6 + .9999999999941207 3.429079977795502e-6 + .9999999999940805 3.4407833224295702e-6 + .9999999999940402 3.452486667063638e-6 + .9999999999939997 3.4641900116977054e-6 + .999999999993959 3.4758933563317723e-6 + .9999999999939183 3.4875967009658384e-6 + .9999999999938775 3.4993000455999045e-6 + .9999999999938364 3.5110033902339697e-6 + .9999999999937953 3.5227067348680345e-6 + .999999999993754 3.534410079502099e-6 + .9999999999937126 3.546113424136163e-6 + .999999999993671 3.5578167687702264e-6 + .9999999999936293 3.5695201134042896e-6 + .9999999999935875 3.581223458038352e-6 + .9999999999935454 3.592926802672414e-6 + .9999999999935033 3.6046301473064755e-6 + .9999999999934611 3.6163334919405365e-6 + .9999999999934187 3.628036836574597e-6 + .9999999999933762 3.639740181208657e-6 + .9999999999933334 3.6514435258427166e-6 + .9999999999932907 3.6631468704767755e-6 + .9999999999932477 3.674850215110834e-6 + .9999999999932047 3.686553559744892e-6 + .9999999999931615 3.6982569043789496e-6 + .9999999999931181 3.7099602490130064e-6 + .9999999999930747 3.7216635936470627e-6 + .999999999993031 3.733366938281119e-6 + .9999999999929873 3.745070282915174e-6 + .9999999999929433 3.756773627549229e-6 + .9999999999928992 3.768476972183284e-6 + .9999999999928552 3.7801803168173377e-6 + .9999999999928109 3.791883661451391e-6 + .9999999999927663 3.803587006085444e-6 + .9999999999927218 3.8152903507194965e-6 + .9999999999926771 3.826993695353548e-6 + .9999999999926322 3.838697039987599e-6 + .9999999999925873 3.85040038462165e-6 + .9999999999925421 3.862103729255701e-6 + .9999999999924968 3.87380707388975e-6 + .9999999999924514 3.885510418523799e-6 + .9999999999924059 3.897213763157848e-6 + .9999999999923602 3.9089171077918965e-6 + .9999999999923144 3.9206204524259435e-6 + .9999999999922684 3.9323237970599905e-6 + .9999999999922223 3.9440271416940376e-6 + .9999999999921761 3.955730486328084e-6 + .9999999999921297 3.967433830962129e-6 + .9999999999920832 3.9791371755961736e-6 + .9999999999920366 3.990840520230218e-6 + .9999999999919899 4.002543864864262e-6 + .9999999999919429 4.014247209498305e-6 + .9999999999918958 4.025950554132348e-6 + .9999999999918486 4.03765389876639e-6 + .9999999999918013 4.049357243400431e-6 + .9999999999917539 4.061060588034472e-6 + .9999999999917063 4.072763932668513e-6 + .9999999999916586 4.084467277302553e-6 + .9999999999916107 4.096170621936592e-6 + .9999999999915626 4.107873966570632e-6 + .9999999999915146 4.119577311204669e-6 + .9999999999914663 4.131280655838707e-6 + .9999999999914179 4.142984000472745e-6 + .9999999999913692 4.154687345106781e-6 + .9999999999913206 4.166390689740817e-6 + .9999999999912718 4.178094034374852e-6 + .9999999999912228 4.189797379008887e-6 + .9999999999911737 4.201500723642921e-6 + .9999999999911244 4.213204068276955e-6 + .999999999991075 4.224907412910988e-6 + .9999999999910255 4.236610757545021e-6 + .9999999999909759 4.248314102179053e-6 + .9999999999909261 4.260017446813084e-6 + .9999999999908762 4.271720791447115e-6 + .9999999999908261 4.283424136081145e-6 + .9999999999907759 4.295127480715175e-6 + .9999999999907256 4.306830825349204e-6 + .9999999999906751 4.3185341699832325e-6 + .9999999999906245 4.33023751461726e-6 + .9999999999905738 4.3419408592512875e-6 + .9999999999905229 4.353644203885314e-6 + .9999999999904718 4.36534754851934e-6 + .9999999999904207 4.377050893153365e-6 + .9999999999903694 4.38875423778739e-6 + .999999999990318 4.400457582421414e-6 + .9999999999902665 4.4121609270554384e-6 + .9999999999902147 4.423864271689461e-6 + .9999999999901629 4.435567616323483e-6 + .9999999999901109 4.447270960957506e-6 + .9999999999900587 4.458974305591527e-6 + .9999999999900065 4.470677650225547e-6 + .9999999999899541 4.482380994859567e-6 + .9999999999899016 4.494084339493587e-6 + .9999999999898489 4.5057876841276054e-6 + .9999999999897962 4.517491028761624e-6 + .9999999999897432 4.529194373395641e-6 + .9999999999896901 4.5408977180296584e-6 + .999999999989637 4.552601062663675e-6 + .9999999999895836 4.564304407297691e-6 + .99999999998953 4.5760077519317055e-6 + .9999999999894764 4.5877110965657195e-6 + .9999999999894227 4.5994144411997335e-6 + .9999999999893688 4.611117785833747e-6 + .9999999999893148 4.622821130467759e-6 + .9999999999892606 4.634524475101771e-6 + .9999999999892063 4.646227819735783e-6 + .9999999999891518 4.657931164369793e-6 + .9999999999890973 4.669634509003803e-6 + .9999999999890425 4.681337853637813e-6 + .9999999999889877 4.693041198271821e-6 + .9999999999889327 4.704744542905829e-6 + .9999999999888776 4.716447887539837e-6 + .9999999999888223 4.728151232173843e-6 + .9999999999887669 4.73985457680785e-6 + .9999999999887114 4.751557921441855e-6 + .9999999999886556 4.76326126607586e-6 + .9999999999885999 4.774964610709864e-6 + .9999999999885439 4.786667955343868e-6 + .9999999999884878 4.798371299977871e-6 + .9999999999884316 4.810074644611873e-6 + .9999999999883752 4.821777989245874e-6 + .9999999999883187 4.833481333879875e-6 + .9999999999882621 4.845184678513876e-6 + .9999999999882053 4.856888023147875e-6 + .9999999999881484 4.868591367781874e-6 + .9999999999880914 4.880294712415872e-6 + .9999999999880341 4.89199805704987e-6 + .9999999999879768 4.903701401683867e-6 + .9999999999879194 4.915404746317863e-6 + .9999999999878618 4.9271080909518585e-6 + .9999999999878041 4.938811435585853e-6 + .9999999999877462 4.9505147802198475e-6 + .9999999999876882 4.962218124853841e-6 + .99999999998763 4.973921469487834e-6 + .9999999999875717 4.985624814121826e-6 + .9999999999875133 4.997328158755817e-6 + .9999999999874548 5.009031503389808e-6 + .9999999999873961 5.0207348480237985e-6 + .9999999999873372 5.032438192657788e-6 + .9999999999872783 5.0441415372917765e-6 + .9999999999872192 5.055844881925764e-6 + .9999999999871599 5.067548226559752e-6 + .9999999999871007 5.079251571193739e-6 + .9999999999870411 5.090954915827725e-6 + .9999999999869814 5.10265826046171e-6 + .9999999999869217 5.1143616050956945e-6 + .9999999999868617 5.126064949729678e-6 + .9999999999868017 5.1377682943636615e-6 + .9999999999867415 5.149471638997644e-6 + .9999999999866811 5.161174983631626e-6 + .9999999999866207 5.172878328265607e-6 + .9999999999865601 5.184581672899587e-6 + .9999999999864994 5.196285017533567e-6 + .9999999999864384 5.2079883621675455e-6 + .9999999999863775 5.219691706801524e-6 + .9999999999863163 5.2313950514355015e-6 + .999999999986255 5.243098396069478e-6 + .9999999999861935 5.254801740703454e-6 + .999999999986132 5.266505085337429e-6 + .9999999999860703 5.278208429971404e-6 + .9999999999860084 5.289911774605378e-6 + .9999999999859465 5.301615119239351e-6 + .9999999999858843 5.313318463873323e-6 + .9999999999858221 5.325021808507295e-6 + .9999999999857597 5.336725153141267e-6 + .9999999999856971 5.3484284977752366e-6 + .9999999999856345 5.360131842409206e-6 + .9999999999855717 5.371835187043175e-6 + .9999999999855087 5.383538531677143e-6 + .9999999999854456 5.3952418763111104e-6 + .9999999999853825 5.406945220945077e-6 + .9999999999853191 5.418648565579043e-6 + .9999999999852557 5.4303519102130076e-6 + .9999999999851921 5.4420552548469724e-6 + .9999999999851282 5.453758599480936e-6 + .9999999999850644 5.465461944114899e-6 + .9999999999850003 5.47716528874886e-6 + .9999999999849362 5.488868633382822e-6 + .9999999999848719 5.500571978016782e-6 + .9999999999848074 5.512275322650742e-6 + .9999999999847429 5.523978667284702e-6 + .9999999999846781 5.53568201191866e-6 + .9999999999846133 5.547385356552617e-6 + .9999999999845482 5.5590887011865745e-6 + .9999999999844832 5.57079204582053e-6 + .9999999999844179 5.582495390454486e-6 + .9999999999843525 5.59419873508844e-6 + .9999999999842869 5.605902079722394e-6 + .9999999999842213 5.617605424356347e-6 + .9999999999841555 5.629308768990299e-6 + .9999999999840895 5.641012113624251e-6 + .9999999999840234 5.652715458258201e-6 + .9999999999839572 5.664418802892152e-6 + .9999999999838908 5.6761221475261e-6 + .9999999999838243 5.687825492160048e-6 + .9999999999837577 5.699528836793996e-6 + .9999999999836909 5.711232181427943e-6 + .999999999983624 5.722935526061889e-6 + .9999999999835569 5.734638870695834e-6 + .9999999999834898 5.746342215329779e-6 + .9999999999834225 5.758045559963722e-6 + .999999999983355 5.769748904597665e-6 + .9999999999832874 5.781452249231607e-6 + .9999999999832196 5.793155593865548e-6 + .9999999999831518 5.804858938499489e-6 + .9999999999830838 5.816562283133429e-6 + .9999999999830157 5.8282656277673675e-6 + .9999999999829474 5.839968972401306e-6 + .9999999999828789 5.851672317035243e-6 + .9999999999828104 5.86337566166918e-6 + .9999999999827417 5.875079006303115e-6 + .9999999999826729 5.88678235093705e-6 + .9999999999826039 5.898485695570985e-6 + .9999999999825349 5.910189040204917e-6 + .9999999999824656 5.92189238483885e-6 + .9999999999823962 5.933595729472782e-6 + .9999999999823267 5.945299074106713e-6 + .9999999999822571 5.957002418740643e-6 + .9999999999821872 5.9687057633745715e-6 + .9999999999821173 5.9804091080085e-6 + ))) + +(define (make-w log-n) + (let ((n (expt 2 log-n))) ;; number of complexes + (if (fx<= n lut-table-size) + low-lut + (let ((result (make-f64vector (fx* 2 n)))) + + (define (copy-low-lut) + (do ((i 0 (fx+ i 1))) + ((fx= i lut-table-size)) + (let ((index (fx* i 2))) + (f64vector-set! + result + index + (f64vector-ref low-lut index)) + (f64vector-set! + result + (fx+ index 1) + (f64vector-ref low-lut (fx+ index 1)))))) + + (define (extend-lut multiplier-lut bit-reverse-size bit-reverse-multiplier start end) + + (define (bit-reverse x n) + (declare (not interrupts-enabled)) + (do ((i 0 (fx+ i 1)) + (x x (fxarithmetic-shift-right x 1)) + (result 0 (fx+ (fx* result 2) + (bitwise-and x 1)))) + ((fx= i n) result))) + + (let loop ((i start) + (j 1)) + (if (fx< i end) + (let* ((multiplier-index + (fx* 2 + (fx* (bit-reverse j bit-reverse-size) + bit-reverse-multiplier))) + (multiplier-real + (f64vector-ref multiplier-lut multiplier-index)) + (multiplier-imag + (f64vector-ref multiplier-lut (fx+ multiplier-index 1)))) + (let inner ((i i) + (k 0)) + ;; we copy complex multiples of all entries below + ;; start to entries starting at start + (if (fx< k start) + (let* ((index + (fx* k 2)) + (real + (f64vector-ref result index)) + (imag + (f64vector-ref result (fx+ index 1))) + (result-real + (fl- (fl* multiplier-real real) + (fl* multiplier-imag imag))) + (result-imag + (fl+ (fl* multiplier-real imag) + (fl* multiplier-imag real))) + (result-index (fx* i 2))) + (f64vector-set! result result-index result-real) + (f64vector-set! result (fx+ result-index 1) result-imag) + (inner (fx+ i 1) + (fx+ k 1))) + (loop i + (fx+ j 1))))) + result))) + + (cond ((fx<= n lut-table-size^2) + (copy-low-lut) + (extend-lut med-lut + (fx- log-n log-lut-table-size) + (fxarithmetic-shift-left 1 (fx- (fx* 2 log-lut-table-size) log-n)) + lut-table-size + n)) + ((fx<= n lut-table-size^3) + (copy-low-lut) + (extend-lut med-lut + log-lut-table-size + 1 + lut-table-size + lut-table-size^2) + (extend-lut high-lut + (fx- log-n (fx* 2 log-lut-table-size)) + (fxarithmetic-shift-left 1 (fx- (fx* 3 log-lut-table-size) log-n)) + lut-table-size^2 + n)) + (else + (error "asking for too large a table"))))))) + +(define (direct-fft-recursive-4 a W-table) + + ;; This is a direcct complex fft, using a decimation-in-time + ;; algorithm with inputs in natural order and outputs in + ;; bit-reversed order. The table of "twiddle" factors is in + ;; bit-reversed order. + + ;; this is from page 66 of Chu and George, except that we have + ;; combined passes in pairs to cut the number of passes through + ;; the vector a + + (let ((W (f64vector 0. 0. 0. 0.))) + + (define (main-loop M N K SizeOfGroup) + + (let inner-loop ((K K) + (JFirst M)) + + (if (fx< JFirst N) + + (let* ((JLast (fx+ JFirst SizeOfGroup))) + + (if (fxeven? K) + (begin + (f64vector-set! W 0 (f64vector-ref W-table K)) + (f64vector-set! W 1 (f64vector-ref W-table (fx+ K 1)))) + (begin + (f64vector-set! W 0 (fl- 0. (f64vector-ref W-table K))) + (f64vector-set! W 1 (f64vector-ref W-table (fx- K 1))))) + + ;; we know the that the next two complex roots of + ;; unity have index 2K and 2K+1 so that the 2K+1 + ;; index root can be gotten from the 2K index root + ;; in the same way that we get W_0 and W_1 from the + ;; table depending on whether K is even or not + + (f64vector-set! W 2 (f64vector-ref W-table (fx* K 2))) + (f64vector-set! W 3 (f64vector-ref W-table (fx+ (fx* K 2) 1))) + + (let J-loop ((J0 JFirst)) + (if (fx< J0 JLast) + + (let* ((J0 J0) + (J1 (fx+ J0 1)) + (J2 (fx+ J0 SizeOfGroup)) + (J3 (fx+ J2 1)) + (J4 (fx+ J2 SizeOfGroup)) + (J5 (fx+ J4 1)) + (J6 (fx+ J4 SizeOfGroup)) + (J7 (fx+ J6 1))) + + (let ((W_0 (f64vector-ref W 0)) + (W_1 (f64vector-ref W 1)) + (W_2 (f64vector-ref W 2)) + (W_3 (f64vector-ref W 3)) + (a_J0 (f64vector-ref a J0)) + (a_J1 (f64vector-ref a J1)) + (a_J2 (f64vector-ref a J2)) + (a_J3 (f64vector-ref a J3)) + (a_J4 (f64vector-ref a J4)) + (a_J5 (f64vector-ref a J5)) + (a_J6 (f64vector-ref a J6)) + (a_J7 (f64vector-ref a J7))) + + ;; first we do the (overlapping) pairs of + ;; butterflies with entries 2*SizeOfGroup + ;; apart. + + (let ((Temp_0 (fl- (fl* W_0 a_J4) + (fl* W_1 a_J5))) + (Temp_1 (fl+ (fl* W_0 a_J5) + (fl* W_1 a_J4))) + (Temp_2 (fl- (fl* W_0 a_J6) + (fl* W_1 a_J7))) + (Temp_3 (fl+ (fl* W_0 a_J7) + (fl* W_1 a_J6)))) + + (let ((a_J0 (fl+ a_J0 Temp_0)) + (a_J1 (fl+ a_J1 Temp_1)) + (a_J2 (fl+ a_J2 Temp_2)) + (a_J3 (fl+ a_J3 Temp_3)) + (a_J4 (fl- a_J0 Temp_0)) + (a_J5 (fl- a_J1 Temp_1)) + (a_J6 (fl- a_J2 Temp_2)) + (a_J7 (fl- a_J3 Temp_3))) + + ;; now we do the two (disjoint) pairs + ;; of butterflies distance SizeOfGroup + ;; apart, the first pair with W2+W3i, + ;; the second with -W3+W2i + + ;; we rewrite the multipliers so I + ;; don't hurt my head too much when + ;; thinking about them. + + (let ((W_0 W_2) + (W_1 W_3) + (W_2 (fl- 0. W_3)) + (W_3 W_2)) + + (let ((Temp_0 + (fl- (fl* W_0 a_J2) + (fl* W_1 a_J3))) + (Temp_1 + (fl+ (fl* W_0 a_J3) + (fl* W_1 a_J2))) + (Temp_2 + (fl- (fl* W_2 a_J6) + (fl* W_3 a_J7))) + (Temp_3 + (fl+ (fl* W_2 a_J7) + (fl* W_3 a_J6)))) + + (let ((a_J0 (fl+ a_J0 Temp_0)) + (a_J1 (fl+ a_J1 Temp_1)) + (a_J2 (fl- a_J0 Temp_0)) + (a_J3 (fl- a_J1 Temp_1)) + (a_J4 (fl+ a_J4 Temp_2)) + (a_J5 (fl+ a_J5 Temp_3)) + (a_J6 (fl- a_J4 Temp_2)) + (a_J7 (fl- a_J5 Temp_3))) + + (f64vector-set! a J0 a_J0) + (f64vector-set! a J1 a_J1) + (f64vector-set! a J2 a_J2) + (f64vector-set! a J3 a_J3) + (f64vector-set! a J4 a_J4) + (f64vector-set! a J5 a_J5) + (f64vector-set! a J6 a_J6) + (f64vector-set! a J7 a_J7) + + (J-loop (fx+ J0 2))))))))) + (inner-loop (fx+ K 1) + (fx+ JFirst (fx* SizeOfGroup 4))))))))) + + (define (recursive-bit M N K SizeOfGroup) + (if (fx<= 2 SizeOfGroup) + (begin + (main-loop M N K SizeOfGroup) + (if (fx< 2048 (fx- N M)) + (let ((new-size (fxarithmetic-shift-right (fx- N M) 2))) + (recursive-bit M + (fx+ M new-size) + (fx* K 4) + (fxarithmetic-shift-right SizeOfGroup 2)) + (recursive-bit (fx+ M new-size) + (fx+ M (fx* new-size 2)) + (fx+ (fx* K 4) 1) + (fxarithmetic-shift-right SizeOfGroup 2)) + (recursive-bit (fx+ M (fx* new-size 2)) + (fx+ M (fx* new-size 3)) + (fx+ (fx* K 4) 2) + (fxarithmetic-shift-right SizeOfGroup 2)) + (recursive-bit (fx+ M (fx* new-size 3)) + N + (fx+ (fx* K 4) 3) + (fxarithmetic-shift-right SizeOfGroup 2))) + (recursive-bit M + N + (fx* K 4) + (fxarithmetic-shift-right SizeOfGroup 2)))))) + + (define (radix-2-pass a) + + ;; If we're here, the size of our (conceptually complex) + ;; array is not a power of 4, so we need to do a basic radix + ;; two pass with w=1 (so W[0]=1.0 and W[1] = 0.) and then + ;; call recursive-bit appropriately on the two half arrays. + + (declare (not interrupts-enabled)) + + (let ((SizeOfGroup + (fxarithmetic-shift-right (f64vector-length a) 1))) + (let loop ((J0 0)) + (if (fx< J0 SizeOfGroup) + (let ((J0 J0) + (J2 (fx+ J0 SizeOfGroup))) + (let ((J1 (fx+ J0 1)) + (J3 (fx+ J2 1))) + (let ((a_J0 (f64vector-ref a J0)) + (a_J1 (f64vector-ref a J1)) + (a_J2 (f64vector-ref a J2)) + (a_J3 (f64vector-ref a J3))) + (let ((a_J0 (fl+ a_J0 a_J2)) + (a_J1 (fl+ a_J1 a_J3)) + (a_J2 (fl- a_J0 a_J2)) + (a_J3 (fl- a_J1 a_J3))) + (f64vector-set! a J0 a_J0) + (f64vector-set! a J1 a_J1) + (f64vector-set! a J2 a_J2) + (f64vector-set! a J3 a_J3) + (loop (fx+ J0 2)))))))))) + + (let* ((n (f64vector-length a)) + (log_n (two^p>=m n))) + + ;; there are n/2 complex entries in a; if n/2 is not a power + ;; of 4, then do a single radix-2 pass and do the rest of + ;; the passes as radix-4 passes + + (if (fxodd? log_n) + (recursive-bit 0 n 0 (fxarithmetic-shift-right n 2)) + (let ((n/2 (fxarithmetic-shift-right n 1)) + (n/8 (fxarithmetic-shift-right n 3))) + (radix-2-pass a) + (recursive-bit 0 n/2 0 n/8) + (recursive-bit n/2 n 1 n/8)))))) + +(define (inverse-fft-recursive-4 a W-table) + + ;; This is an complex fft, using a decimation-in-frequency algorithm + ;; with inputs in bit-reversed order and outputs in natural order. + + ;; The organization of the algorithm has little to do with the the + ;; associated algorithm on page 41 of Chu and George, + ;; I just reversed the operations of the direct algorithm given + ;; above (without dividing by 2 each time, so that this has to + ;; be "normalized" by dividing by N/2 at the end. + + ;; The table of "twiddle" factors is in bit-reversed order. + + (let ((W (f64vector 0. 0. 0. 0.))) + + (define (main-loop M N K SizeOfGroup) + (let inner-loop ((K K) + (JFirst M)) + (if (fx< JFirst N) + (let* ((JLast (fx+ JFirst SizeOfGroup))) + (if (fxeven? K) + (begin + (f64vector-set! W 0 (f64vector-ref W-table K)) + (f64vector-set! W 1 (f64vector-ref W-table (fx+ K 1)))) + (begin + (f64vector-set! W 0 (fl- 0. (f64vector-ref W-table K))) + (f64vector-set! W 1 (f64vector-ref W-table (fx- K 1))))) + (f64vector-set! W 2 (f64vector-ref W-table (fx* K 2))) + (f64vector-set! W 3 (f64vector-ref W-table (fx+ (fx* K 2) 1))) + (let J-loop ((J0 JFirst)) + (if (fx< J0 JLast) + (let* ((J0 J0) + (J1 (fx+ J0 1)) + (J2 (fx+ J0 SizeOfGroup)) + (J3 (fx+ J2 1)) + (J4 (fx+ J2 SizeOfGroup)) + (J5 (fx+ J4 1)) + (J6 (fx+ J4 SizeOfGroup)) + (J7 (fx+ J6 1))) + (let ((W_0 (f64vector-ref W 0)) + (W_1 (f64vector-ref W 1)) + (W_2 (f64vector-ref W 2)) + (W_3 (f64vector-ref W 3)) + (a_J0 (f64vector-ref a J0)) + (a_J1 (f64vector-ref a J1)) + (a_J2 (f64vector-ref a J2)) + (a_J3 (f64vector-ref a J3)) + (a_J4 (f64vector-ref a J4)) + (a_J5 (f64vector-ref a J5)) + (a_J6 (f64vector-ref a J6)) + (a_J7 (f64vector-ref a J7))) + (let ((W_00 W_2) + (W_01 W_3) + (W_02 (fl- 0. W_3)) + (W_03 W_2)) + (let ((Temp_0 (fl- a_J0 a_J2)) + (Temp_1 (fl- a_J1 a_J3)) + (Temp_2 (fl- a_J4 a_J6)) + (Temp_3 (fl- a_J5 a_J7))) + (let ((a_J0 (fl+ a_J0 a_J2)) + (a_J1 (fl+ a_J1 a_J3)) + (a_J4 (fl+ a_J4 a_J6)) + (a_J5 (fl+ a_J5 a_J7)) + (a_J2 (fl+ (fl* W_00 Temp_0) + (fl* W_01 Temp_1))) + (a_J3 (fl- (fl* W_00 Temp_1) + (fl* W_01 Temp_0))) + (a_J6 (fl+ (fl* W_02 Temp_2) + (fl* W_03 Temp_3))) + (a_J7 (fl- (fl* W_02 Temp_3) + (fl* W_03 Temp_2)))) + (let ((Temp_0 (fl- a_J0 a_J4)) + (Temp_1 (fl- a_J1 a_J5)) + (Temp_2 (fl- a_J2 a_J6)) + (Temp_3 (fl- a_J3 a_J7))) + (let ((a_J0 (fl+ a_J0 a_J4)) + (a_J1 (fl+ a_J1 a_J5)) + (a_J2 (fl+ a_J2 a_J6)) + (a_J3 (fl+ a_J3 a_J7)) + (a_J4 (fl+ (fl* W_0 Temp_0) + (fl* W_1 Temp_1))) + (a_J5 (fl- (fl* W_0 Temp_1) + (fl* W_1 Temp_0))) + (a_J6 (fl+ (fl* W_0 Temp_2) + (fl* W_1 Temp_3))) + (a_J7 (fl- (fl* W_0 Temp_3) + (fl* W_1 Temp_2)))) + (f64vector-set! a J0 a_J0) + (f64vector-set! a J1 a_J1) + (f64vector-set! a J2 a_J2) + (f64vector-set! a J3 a_J3) + (f64vector-set! a J4 a_J4) + (f64vector-set! a J5 a_J5) + (f64vector-set! a J6 a_J6) + (f64vector-set! a J7 a_J7) + (J-loop (fx+ J0 2))))))))) + (inner-loop (fx+ K 1) + (fx+ JFirst (fx* SizeOfGroup 4))))))))) + + (define (recursive-bit M N K SizeOfGroup) + (if (fx<= 2 SizeOfGroup) + (begin + (if (fx< 2048 (fx- N M)) + (let ((new-size (fxarithmetic-shift-right (fx- N M) 2))) + (recursive-bit M + (fx+ M new-size) + (fx* K 4) + (fxarithmetic-shift-right SizeOfGroup 2)) + (recursive-bit (fx+ M new-size) + (fx+ M (fx* new-size 2)) + (fx+ (fx* K 4) 1) + (fxarithmetic-shift-right SizeOfGroup 2)) + (recursive-bit (fx+ M (fx* new-size 2)) + (fx+ M (fx* new-size 3)) + (fx+ (fx* K 4) 2) + (fxarithmetic-shift-right SizeOfGroup 2)) + (recursive-bit (fx+ M (fx* new-size 3)) + N + (fx+ (fx* K 4) 3) + (fxarithmetic-shift-right SizeOfGroup 2))) + (recursive-bit M + N + (fx* K 4) + (fxarithmetic-shift-right SizeOfGroup 2))) + (main-loop M N K SizeOfGroup)))) + + (define (radix-2-pass a) + (declare (not interrupts-enabled)) + (let ((SizeOfGroup + (fxarithmetic-shift-right (f64vector-length a) 1))) + (let loop ((J0 0)) + (if (fx< J0 SizeOfGroup) + (let ((J0 J0) + (J2 (fx+ J0 SizeOfGroup))) + (let ((J1 (fx+ J0 1)) + (J3 (fx+ J2 1))) + (let ((a_J0 (f64vector-ref a J0)) + (a_J1 (f64vector-ref a J1)) + (a_J2 (f64vector-ref a J2)) + (a_J3 (f64vector-ref a J3))) + (let ((a_J0 (fl+ a_J0 a_J2)) + (a_J1 (fl+ a_J1 a_J3)) + (a_J2 (fl- a_J0 a_J2)) + (a_J3 (fl- a_J1 a_J3))) + (f64vector-set! a J0 a_J0) + (f64vector-set! a J1 a_J1) + (f64vector-set! a J2 a_J2) + (f64vector-set! a J3 a_J3) + (loop (fx+ J0 2)))))))))) + + (let* ((n (f64vector-length a)) + (log_n (two^p>=m n))) + (if (fxodd? log_n) + (recursive-bit 0 n 0 (fxarithmetic-shift-right n 2)) + (let ((n/2 (fxarithmetic-shift-right n 1)) + (n/8 (fxarithmetic-shift-right n 3))) + (recursive-bit 0 n/2 0 n/8) + (recursive-bit n/2 n 1 n/8) + (radix-2-pass a)))))) + +(define (two^p>=m m) + ;; returns smallest p, assumes fixnum m >= 0 + (do ((p 0 (fx+ p 1)) + (two^p 1 (fx* two^p 2))) + ((fx<= m two^p) p))) + +(define (test iters n) + (let ((two^n + (expt 2 n)) + (table + (make-w (fx- n 1)))) + (display (fx* two^n 2))(newline) + (let ((a + (make-f64vector (fx* two^n 2) 0.))) + (do ((i 0 (fx+ i 1))) + ((fx= i iters)) + (direct-fft-recursive-4 a table) + (inverse-fft-recursive-4 a table))))) + +(test 2000 11) diff --git a/tests/runtests.sh b/tests/runtests.sh index 95f9fb7e..84af3fc1 100644 --- a/tests/runtests.sh +++ b/tests/runtests.sh @@ -210,4 +210,8 @@ $compile -e embedded2.scm echo "======================================== timing compilation ..." time $compile silex.scm -t -S -O3 +echo "======================================== running floating-point benchmark ..." +$compile fft.scm -O4 -d0 -disable-interrupts -unsafe-libraries +time ./a.out + echo "======================================== done."Trap