2 ** Algorithm: complex multiplication
4 ** Performance: Bad accuracy, great speed.
6 ** The simplest, way of generating trig values. Note, this method is
7 ** not stable, and errors accumulate rapidly.
9 ** Computation: 2 *, 1 + per value.
19 char mtrig_algorithm
[] = "Simple";
22 #define TRIG_INIT(k,c,s) \
29 #define TRIG_NEXT(k,c,s) \
32 c = mult(t,t_c) - mult(s,t_s); \
33 s = mult(t,t_s) + mult(s,t_c); \
35 #define TRIG_23(k,c1,s1,c2,s2,c3,s3) \
37 c2 = mult(c1,c1) - mult(s1,s1); \
38 s2 = (mult(c1,s1)<<2); \
39 c3 = mult(c2,c1) - mult(s2,s1); \
40 s3 = mult(c2,s1) + mult(s2,c1); \
43 #define TRIG_RESET(k,c,s)
46 ** Algorithm: O. Buneman's trig generator.
48 ** Performance: Good accuracy, mediocre speed.
50 ** Manipulates a log(n) table to stably create n evenly spaced trig
51 ** values. The newly generated values lay halfway between two
52 ** known values, and are calculated by appropriatelly scaling the
53 ** average of the known trig values appropriatelly according to the
54 ** angle between them. This process is inherently stable; and is
55 ** about as accurate as most trig library functions. The errors
56 ** caused by this code segment are primarily due to the less stable
57 ** method to calculate values for 2t and s 3t. Note: I believe this
58 ** algorithm is patented(!), see readme file for more details.
60 ** Computation: 1 +, 1 *, much integer math, per trig value
67 double coswrk[TRIG_TABLE_SIZE],sinwrk[TRIG_TABLE_SIZE];
68 #define TRIG_INIT(k,c,s) \
71 for (i=0 ; i<=k ; i++) \
72 {coswrk[i]=fcostab[i];sinwrk[i]=fsintab[i];} \
77 #define TRIG_NEXT(k,c,s) \
81 for (i=0 ; !((1<<i)&t_lam) ; i++); \
87 for (j=k-i+2 ; (1<<j)&t_lam ; j++); \
89 sinwrk[i] = halsec[i] * (sinwrk[i-1] + sinwrk[j]); \
90 coswrk[i] = halsec[i] * (coswrk[i-1] + coswrk[j]); \
96 #define TRIG_TAB_SIZE 22
98 static long long halsec
[TRIG_TAB_SIZE
]= {1,2,3};
100 #define FFTmult(x,y) mult(x,y)
105 #include "d_imayer_tables.h"
107 #define SQRT2 ftofix(1.414213562373095048801688724209698)
110 void imayer_fht(t_fixed
*fz
, int n
)
112 int k
,k1
,k2
,k3
,k4
,kx
;
116 for (k1
=1,k2
=0;k1
<n
;k1
++)
119 for (k
=n
>>1; (!((k2
^=k
)&k
)); k
>>=1);
122 aa
=fz
[k1
];fz
[k1
]=fz
[k2
];fz
[k2
]=aa
;
125 for ( k
=0 ; (1<<k
)<n
; k
++ );
129 for (fi
=fz
,fn
=fz
+n
;fi
<fn
;fi
+=4)
144 for (fi
=fz
,fn
=fz
+n
,gi
=fi
+1;fi
<fn
;fi
+=8,gi
+=8)
146 t_fixed bs1
,bc1
,bs2
,bc2
,bs3
,bc3
,bs4
,bc4
,
147 bg0
,bf0
,bf1
,bg1
,bf2
,bg2
,bf3
,bg3
;
148 bc1
= fi
[0 ] - gi
[0 ];
149 bs1
= fi
[0 ] + gi
[0 ];
150 bc2
= fi
[2 ] - gi
[2 ];
151 bs2
= fi
[2 ] + gi
[2 ];
152 bc3
= fi
[4 ] - gi
[4 ];
153 bs3
= fi
[4 ] + gi
[4 ];
154 bc4
= fi
[6 ] - gi
[6 ];
155 bs4
= fi
[6 ] + gi
[6 ];
162 bg3
= FFTmult(SQRT2
,bc4
);
163 bg2
= FFTmult(SQRT2
,bc3
);
191 t_fixed g0
,f0
,f1
,g1
,f2
,g2
,f3
,g3
;
192 f1
= fi
[0 ] - fi
[k1
];
193 f0
= fi
[0 ] + fi
[k1
];
194 f3
= fi
[k2
] - fi
[k3
];
195 f2
= fi
[k2
] + fi
[k3
];
200 g1
= gi
[0 ] - gi
[k1
];
201 g0
= gi
[0 ] + gi
[k1
];
202 g3
= FFTmult(SQRT2
, gi
[k3
]);
203 g2
= FFTmult(SQRT2
, gi
[k2
]);
212 for (ii
=1;ii
<kx
;ii
++)
216 c2
= FFTmult(c1
,c1
) - FFTmult(s1
,s1
);
217 s2
= 2*FFTmult(c1
,s1
);
223 t_fixed a
,b
,g0
,f0
,f1
,g1
,f2
,g2
,f3
,g3
;
224 b
= FFTmult(s2
,fi
[k1
]) - FFTmult(c2
,gi
[k1
]);
225 a
= FFTmult(c2
,fi
[k1
]) + FFTmult(s2
,gi
[k1
]);
230 b
= FFTmult(s2
,fi
[k3
]) - FFTmult(c2
,gi
[k3
]);
231 a
= FFTmult(c2
,fi
[k3
]) + FFTmult(s2
,gi
[k3
]);
236 b
= FFTmult(s1
,f2
) - FFTmult(c1
,g3
);
237 a
= FFTmult(c1
,f2
) + FFTmult(s1
,g3
);
242 b
= FFTmult(c1
,g2
) - FFTmult(s1
,f3
);
243 a
= FFTmult(s1
,g2
) + FFTmult(c1
,f3
);
257 void imayer_fft(int n
, t_fixed
*real
, t_fixed
*imag
)
262 for (i
=1,j
=n
-1,k
=n
/2;i
<k
;i
++,j
--) {
263 a
= real
[i
]; b
= real
[j
]; q
=a
+b
; r
=a
-b
;
264 c
= imag
[i
]; d
= imag
[j
]; s
=c
+d
; t
=c
-d
;
265 real
[i
] = (q
+t
)>>1; real
[j
] = (q
-t
)>>1;
266 imag
[i
] = (s
-r
)>>1; imag
[j
] = (s
+r
)>>1;
272 void imayer_ifft(int n
, t_fixed
*real
, t_fixed
*imag
)
279 for (i
=1,j
=n
-1,k
=n
/2;i
<k
;i
++,j
--) {
280 a
= real
[i
]; b
= real
[j
]; q
=a
+b
; r
=a
-b
;
281 c
= imag
[i
]; d
= imag
[j
]; s
=c
+d
; t
=c
-d
;
282 imag
[i
] = (s
+r
)>>1; imag
[j
] = (s
-r
)>>1;
283 real
[i
] = (q
-t
)>>1; real
[j
] = (q
+t
)>>1;
287 void imayer_realfft(int n
, t_fixed
*real
)
292 for (i
=1,j
=n
-1,k
=n
/2;i
<k
;i
++,j
--) {
300 void imayer_realifft(int n
, t_fixed
*real
)
304 for (i
=1,j
=n
-1,k
=n
/2;i
<k
;i
++,j
--) {
317 static double dfcostab
[TRIG_TAB_SIZE
]=
319 .00000000000000000000000000000000000000000000000000,
320 .70710678118654752440084436210484903928483593768847,
321 .92387953251128675612818318939678828682241662586364,
322 .98078528040323044912618223613423903697393373089333,
323 .99518472667219688624483695310947992157547486872985,
324 .99879545620517239271477160475910069444320361470461,
325 .99969881869620422011576564966617219685006108125772,
326 .99992470183914454092164649119638322435060646880221,
327 .99998117528260114265699043772856771617391725094433,
328 .99999529380957617151158012570011989955298763362218,
329 .99999882345170190992902571017152601904826792288976,
330 .99999970586288221916022821773876567711626389934930,
331 .99999992646571785114473148070738785694820115568892,
332 .99999998161642929380834691540290971450507605124278,
333 .99999999540410731289097193313960614895889430318945,
334 .99999999885102682756267330779455410840053741619428,
335 .99999999971275670684941397221864177608908945791828,
336 .99999999992818917670977509588385049026048033310951
338 static double dfsintab
[TRIG_TAB_SIZE
]=
340 1.0000000000000000000000000000000000000000000000000,
341 .70710678118654752440084436210484903928483593768846,
342 .38268343236508977172845998403039886676134456248561,
343 .19509032201612826784828486847702224092769161775195,
344 .09801714032956060199419556388864184586113667316749,
345 .04906767432741801425495497694268265831474536302574,
346 .02454122852291228803173452945928292506546611923944,
347 .01227153828571992607940826195100321214037231959176,
348 .00613588464915447535964023459037258091705788631738,
349 .00306795676296597627014536549091984251894461021344,
350 .00153398018628476561230369715026407907995486457522,
351 .00076699031874270452693856835794857664314091945205,
352 .00038349518757139558907246168118138126339502603495,
353 .00019174759731070330743990956198900093346887403385,
354 .00009587379909597734587051721097647635118706561284,
355 .00004793689960306688454900399049465887274686668768,
356 .00002396844980841821872918657716502182009476147489,
357 .00001198422490506970642152156159698898480473197753
360 static double dhalsec
[TRIG_TAB_SIZE
]=
364 .54119610014619698439972320536638942006107206337801,
365 .50979557910415916894193980398784391368261849190893,
366 .50241928618815570551167011928012092247859337193963,
367 .50060299823519630134550410676638239611758632599591,
368 .50015063602065098821477101271097658495974913010340,
369 .50003765191554772296778139077905492847503165398345,
370 .50000941253588775676512870469186533538523133757983,
371 .50000235310628608051401267171204408939326297376426,
372 .50000058827484117879868526730916804925780637276181,
373 .50000014706860214875463798283871198206179118093251,
374 .50000003676714377807315864400643020315103490883972,
375 .50000000919178552207366560348853455333939112569380,
376 .50000000229794635411562887767906868558991922348920,
377 .50000000057448658687873302235147272458812263401372,
378 .50000000014362164661654736863252589967935073278768,
379 .50000000003590541164769084922906986545517021050714
390 printf("/* Tables for fixed point lookup with %d bit precision*/\n\n",fix1
);
392 printf("static int fsintab[TRIG_TAB_SIZE]= {\n");
394 for (i
=0;i
<TRIG_TAB_SIZE
-1;i
++)
395 printf("%ld, \n",ftofix(dfsintab
[i
]));
396 printf("%ld }; \n",ftofix(dfsintab
[i
]));
399 printf("\n\nstatic int fcostab[TRIG_TAB_SIZE]= {\n");
401 for (i
=0;i
<TRIG_TAB_SIZE
-1;i
++)
402 printf("%ld, \n",ftofix(dfcostab
[i
]));
403 printf("%ld }; \n",ftofix(dfcostab
[i
]));
409 fprintf(stderr,"Integer - Float\n");\
411 fprintf(stderr,"%f %f --> %f %f\n",fixtof(r[i]),fixtof(im[i]),\
413 fprintf(stderr,"\n\n");
433 t_fixed c1
,s1
,c2
,s2
,c3
,s3
;
439 for (k
=2;k
<10;k
+=2) {
443 TRIG_23(k
,c1
,s1
,c2
,s2
,c3
,s3
);
444 printf("TRIG value k=%d,%d val1 = %f %f\n",k
,i
,fixtof(c1
),fixtof(s1
));
466 r
[i
] = ftofix(0.1*i
);
491 mayer_fft(NP
,fr
,fim
);
497 r
[i
] = mult(ftofix(0.01),r
[i
]);
506 mayer_fft(NP
,fr
,fim
);
518 ** Algorithm: complex multiplication
520 ** Performance: Bad accuracy, great speed.
522 ** The simplest, way of generating trig values. Note, this method is
523 ** not stable, and errors accumulate rapidly.
525 ** Computation: 2 *, 1 + per value.
535 char mtrig_algorithm
[] = "Simple";
538 #define TRIG_INIT(k,c,s) \
545 #define TRIG_NEXT(k,c,s) \
548 c = mult(t,t_c) - mult(s,t_s); \
549 s = mult(t,t_s) + mult(s,t_c); \
551 #define TRIG_23(k,c1,s1,c2,s2,c3,s3) \
553 c2 = mult(c1,c1) - mult(s1,s1); \
554 s2 = (mult(c1,s1)<<2); \
555 c3 = mult(c2,c1) - mult(s2,s1); \
556 s3 = mult(c2,s1) + mult(s2,c1); \
559 #define TRIG_RESET(k,c,s)
562 ** Algorithm: O. Buneman's trig generator.
564 ** Performance: Good accuracy, mediocre speed.
566 ** Manipulates a log(n) table to stably create n evenly spaced trig
567 ** values. The newly generated values lay halfway between two
568 ** known values, and are calculated by appropriatelly scaling the
569 ** average of the known trig values appropriatelly according to the
570 ** angle between them. This process is inherently stable; and is
571 ** about as accurate as most trig library functions. The errors
572 ** caused by this code segment are primarily due to the less stable
573 ** method to calculate values for 2t and s 3t. Note: I believe this
574 ** algorithm is patented(!), see readme file for more details.
576 ** Computation: 1 +, 1 *, much integer math, per trig value
583 double coswrk[TRIG_TABLE_SIZE],sinwrk[TRIG_TABLE_SIZE];
584 #define TRIG_INIT(k,c,s) \
587 for (i=0 ; i<=k ; i++) \
588 {coswrk[i]=fcostab[i];sinwrk[i]=fsintab[i];} \
593 #define TRIG_NEXT(k,c,s) \
597 for (i=0 ; !((1<<i)&t_lam) ; i++); \
603 for (j=k-i+2 ; (1<<j)&t_lam ; j++); \
605 sinwrk[i] = halsec[i] * (sinwrk[i-1] + sinwrk[j]); \
606 coswrk[i] = halsec[i] * (coswrk[i-1] + coswrk[j]); \
612 #define TRIG_TAB_SIZE 22
614 static long long halsec
[TRIG_TAB_SIZE
]= {1,2,3};
616 #define FFTmult(x,y) mult(x,y)
621 #include "d_imayer_tables.h"
623 #define SQRT2 ftofix(1.414213562373095048801688724209698)
626 void imayer_fht(t_fixed
*fz
, int n
)
628 int k
,k1
,k2
,k3
,k4
,kx
;
632 for (k1
=1,k2
=0;k1
<n
;k1
++)
635 for (k
=n
>>1; (!((k2
^=k
)&k
)); k
>>=1);
638 aa
=fz
[k1
];fz
[k1
]=fz
[k2
];fz
[k2
]=aa
;
641 for ( k
=0 ; (1<<k
)<n
; k
++ );
645 for (fi
=fz
,fn
=fz
+n
;fi
<fn
;fi
+=4)
660 for (fi
=fz
,fn
=fz
+n
,gi
=fi
+1;fi
<fn
;fi
+=8,gi
+=8)
662 t_fixed bs1
,bc1
,bs2
,bc2
,bs3
,bc3
,bs4
,bc4
,
663 bg0
,bf0
,bf1
,bg1
,bf2
,bg2
,bf3
,bg3
;
664 bc1
= fi
[0 ] - gi
[0 ];
665 bs1
= fi
[0 ] + gi
[0 ];
666 bc2
= fi
[2 ] - gi
[2 ];
667 bs2
= fi
[2 ] + gi
[2 ];
668 bc3
= fi
[4 ] - gi
[4 ];
669 bs3
= fi
[4 ] + gi
[4 ];
670 bc4
= fi
[6 ] - gi
[6 ];
671 bs4
= fi
[6 ] + gi
[6 ];
678 bg3
= FFTmult(SQRT2
,bc4
);
679 bg2
= FFTmult(SQRT2
,bc3
);
707 t_fixed g0
,f0
,f1
,g1
,f2
,g2
,f3
,g3
;
708 f1
= fi
[0 ] - fi
[k1
];
709 f0
= fi
[0 ] + fi
[k1
];
710 f3
= fi
[k2
] - fi
[k3
];
711 f2
= fi
[k2
] + fi
[k3
];
716 g1
= gi
[0 ] - gi
[k1
];
717 g0
= gi
[0 ] + gi
[k1
];
718 g3
= FFTmult(SQRT2
, gi
[k3
]);
719 g2
= FFTmult(SQRT2
, gi
[k2
]);
728 for (ii
=1;ii
<kx
;ii
++)
732 c2
= FFTmult(c1
,c1
) - FFTmult(s1
,s1
);
733 s2
= 2*FFTmult(c1
,s1
);
739 t_fixed a
,b
,g0
,f0
,f1
,g1
,f2
,g2
,f3
,g3
;
740 b
= FFTmult(s2
,fi
[k1
]) - FFTmult(c2
,gi
[k1
]);
741 a
= FFTmult(c2
,fi
[k1
]) + FFTmult(s2
,gi
[k1
]);
746 b
= FFTmult(s2
,fi
[k3
]) - FFTmult(c2
,gi
[k3
]);
747 a
= FFTmult(c2
,fi
[k3
]) + FFTmult(s2
,gi
[k3
]);
752 b
= FFTmult(s1
,f2
) - FFTmult(c1
,g3
);
753 a
= FFTmult(c1
,f2
) + FFTmult(s1
,g3
);
758 b
= FFTmult(c1
,g2
) - FFTmult(s1
,f3
);
759 a
= FFTmult(s1
,g2
) + FFTmult(c1
,f3
);
773 void imayer_fft(int n
, t_fixed
*real
, t_fixed
*imag
)
778 for (i
=1,j
=n
-1,k
=n
/2;i
<k
;i
++,j
--) {
779 a
= real
[i
]; b
= real
[j
]; q
=a
+b
; r
=a
-b
;
780 c
= imag
[i
]; d
= imag
[j
]; s
=c
+d
; t
=c
-d
;
781 real
[i
] = (q
+t
)>>1; real
[j
] = (q
-t
)>>1;
782 imag
[i
] = (s
-r
)>>1; imag
[j
] = (s
+r
)>>1;
788 void imayer_ifft(int n
, t_fixed
*real
, t_fixed
*imag
)
795 for (i
=1,j
=n
-1,k
=n
/2;i
<k
;i
++,j
--) {
796 a
= real
[i
]; b
= real
[j
]; q
=a
+b
; r
=a
-b
;
797 c
= imag
[i
]; d
= imag
[j
]; s
=c
+d
; t
=c
-d
;
798 imag
[i
] = (s
+r
)>>1; imag
[j
] = (s
-r
)>>1;
799 real
[i
] = (q
-t
)>>1; real
[j
] = (q
+t
)>>1;
803 void imayer_realfft(int n
, t_fixed
*real
)
808 for (i
=1,j
=n
-1,k
=n
/2;i
<k
;i
++,j
--) {
816 void imayer_realifft(int n
, t_fixed
*real
)
820 for (i
=1,j
=n
-1,k
=n
/2;i
<k
;i
++,j
--) {
833 static double dfcostab
[TRIG_TAB_SIZE
]=
835 .00000000000000000000000000000000000000000000000000,
836 .70710678118654752440084436210484903928483593768847,
837 .92387953251128675612818318939678828682241662586364,
838 .98078528040323044912618223613423903697393373089333,
839 .99518472667219688624483695310947992157547486872985,
840 .99879545620517239271477160475910069444320361470461,
841 .99969881869620422011576564966617219685006108125772,
842 .99992470183914454092164649119638322435060646880221,
843 .99998117528260114265699043772856771617391725094433,
844 .99999529380957617151158012570011989955298763362218,
845 .99999882345170190992902571017152601904826792288976,
846 .99999970586288221916022821773876567711626389934930,
847 .99999992646571785114473148070738785694820115568892,
848 .99999998161642929380834691540290971450507605124278,
849 .99999999540410731289097193313960614895889430318945,
850 .99999999885102682756267330779455410840053741619428,
851 .99999999971275670684941397221864177608908945791828,
852 .99999999992818917670977509588385049026048033310951
854 static double dfsintab
[TRIG_TAB_SIZE
]=
856 1.0000000000000000000000000000000000000000000000000,
857 .70710678118654752440084436210484903928483593768846,
858 .38268343236508977172845998403039886676134456248561,
859 .19509032201612826784828486847702224092769161775195,
860 .09801714032956060199419556388864184586113667316749,
861 .04906767432741801425495497694268265831474536302574,
862 .02454122852291228803173452945928292506546611923944,
863 .01227153828571992607940826195100321214037231959176,
864 .00613588464915447535964023459037258091705788631738,
865 .00306795676296597627014536549091984251894461021344,
866 .00153398018628476561230369715026407907995486457522,
867 .00076699031874270452693856835794857664314091945205,
868 .00038349518757139558907246168118138126339502603495,
869 .00019174759731070330743990956198900093346887403385,
870 .00009587379909597734587051721097647635118706561284,
871 .00004793689960306688454900399049465887274686668768,
872 .00002396844980841821872918657716502182009476147489,
873 .00001198422490506970642152156159698898480473197753
876 static double dhalsec
[TRIG_TAB_SIZE
]=
880 .54119610014619698439972320536638942006107206337801,
881 .50979557910415916894193980398784391368261849190893,
882 .50241928618815570551167011928012092247859337193963,
883 .50060299823519630134550410676638239611758632599591,
884 .50015063602065098821477101271097658495974913010340,
885 .50003765191554772296778139077905492847503165398345,
886 .50000941253588775676512870469186533538523133757983,
887 .50000235310628608051401267171204408939326297376426,
888 .50000058827484117879868526730916804925780637276181,
889 .50000014706860214875463798283871198206179118093251,
890 .50000003676714377807315864400643020315103490883972,
891 .50000000919178552207366560348853455333939112569380,
892 .50000000229794635411562887767906868558991922348920,
893 .50000000057448658687873302235147272458812263401372,
894 .50000000014362164661654736863252589967935073278768,
895 .50000000003590541164769084922906986545517021050714
906 printf("/* Tables for fixed point lookup with %d bit precision*/\n\n",fix1
);
908 printf("static int fsintab[TRIG_TAB_SIZE]= {\n");
910 for (i
=0;i
<TRIG_TAB_SIZE
-1;i
++)
911 printf("%ld, \n",ftofix(dfsintab
[i
]));
912 printf("%ld }; \n",ftofix(dfsintab
[i
]));
915 printf("\n\nstatic int fcostab[TRIG_TAB_SIZE]= {\n");
917 for (i
=0;i
<TRIG_TAB_SIZE
-1;i
++)
918 printf("%ld, \n",ftofix(dfcostab
[i
]));
919 printf("%ld }; \n",ftofix(dfcostab
[i
]));
925 fprintf(stderr,"Integer - Float\n");\
927 fprintf(stderr,"%f %f --> %f %f\n",fixtof(r[i]),fixtof(im[i]),\
929 fprintf(stderr,"\n\n");
949 t_fixed c1
,s1
,c2
,s2
,c3
,s3
;
955 for (k
=2;k
<10;k
+=2) {
959 TRIG_23(k
,c1
,s1
,c2
,s2
,c3
,s3
);
960 printf("TRIG value k=%d,%d val1 = %f %f\n",k
,i
,fixtof(c1
),fixtof(s1
));
982 r
[i
] = ftofix(0.1*i
);
1006 imayer_fft(NP
,r
,im
);
1007 mayer_fft(NP
,fr
,fim
);
1008 // imayer_fht(r,NP);
1009 // mayer_fht(fr,NP);
1012 for (i
=0;i
<NP
;i
++) {
1013 r
[i
] = mult(ftofix(0.01),r
[i
]);
1021 imayer_fft(NP
,r
,im
);
1022 mayer_fft(NP
,fr
,fim
);