/*
* sincos_table.c: 三角関数をテーブル引きにして高速化
*
* [2002/08/16] OSHIRO Naoki. <oshiro@mibai.tec.u-ryukyu.ac.jp>
*
*/
/* compile: gcc -O3 -c sincos_table.c */
/* 最適化オプション(-O3 など)を必ず付けること! */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
static int SinCos_num=-1;
static double *SinCos_table=NULL;
/*#include "sincos_table.h"*/
/* SinCos_init: 90度分の cos() テーブルを作成する */
void SinCos_init(int num)
{
int i;
if (num<=0) {
fprintf(stderr
, "SinCos: specified init number error (%d).\n", num
); }
SinCos_table
=malloc(sizeof(double)*num
); if (SinCos_table==NULL) {
fprintf(stderr
, "SinCos: not enough memory.\n"); }
SinCos_num=num;
for (i=0; i<num; i++) {
SinCos_table
[i
]=cos(i
*M_PI
/2/num
); }
}
/* SinCos テーブル範囲を毎回チェック.定義すると安全だが20倍は遅くなる */
#undef SINCOS_CHECK
/* Cos() 関数 */
double Cos(double x)
{
double sign=1;
int i;
#ifdef SINCOS_CHECK
if (SinCos_num<=0) {
fprintf(stderr
, "Not initialize SinCos_table.\n"); }
#endif
if (x<0) x=-x; /* cos(x)=cos(-x) */
x/=M_PI;
x=(x-(int)(x/2)*2); /* cos(x)=cos(x+2*PI) */
if (x>1) x=2-x; /* cos(x)=cos(x-PI) */
if (x>.5) {x=1-x; sign=-1;} /* -cos(x)=cos(PI-x) */
i=(int)(x*2*SinCos_num);
#ifdef SINCOS_CHECK
if (i<0 || i>=SinCos_num) {
fprintf(stderr
, "SinCos: specified number out of range (%d).\n", i
); }
#endif
return (sign*SinCos_table[i]);
}
/************************************************************/
/*#ifdef SINCOS_TABLE_TEST*/
#include <time.h>
int main(void)
{
int i, j, num;
clock_t t;
double x = 0;
/* SinCosテーブル初期化 */
/* 分割数と誤差の目安: 分割数 1e+X, 誤差 1e-(X+1) */
num=1e+5;
SinCos_init(num);
printf("SinCos_Table:%d\n", num
); #if 0
/* 0.01 [rad] 刻みで sin() と Sin(), cos() と Cos() の精度比較をする */
printf("x,sin(),Sin(),sin()-Sin(x)\n"); for (x=-10; x<10; x+=0.01) {
}
printf("x,cos(),Cos(),cos()-Cos(x)\n"); for (x=-10; x<10; x+=0.01) {
}
#endif
/* cos() と Cos() の速度比較 */
printf("Time benchmark: cos(), Cos()\n"); /* cos() */
for (i=0; i<50000; i++)
for (j=0; j<10000; j++)
printf("cos:%.2fsec\n", (double)(clock()-t
) / CLOCKS_PER_SEC
);
/* Cos() */
for (i=0; i<50000; i++)
for (j=0; j<10000; j++)
x += Cos(.1);
printf("Cos:%.2fsec\n", (double)(clock()-t
) / CLOCKS_PER_SEC
); return (int)x;
}
/*#endif /* SINCOS_TABLE_TEST */
LyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogKiBzaW5jb3NfdGFibGUuYzog5LiJ6KeS6Zai5pWw44KS44OG44O844OW44Or5byV44GN44Gr44GX44Gm6auY6YCf5YyWICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogKiAgICAgWzIwMDIvMDgvMTZdIE9TSElSTyBOYW9raS4gPG9zaGlyb0BtaWJhaS50ZWMudS1yeXVreXUuYWMuanA+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICovCgovKiBjb21waWxlOiBnY2MgLU8zIC1jIHNpbmNvc190YWJsZS5jICovCi8qIOacgOmBqeWMluOCquODl+OCt+ODp+ODs++8iC1PMyDjgarjganvvInjgpLlv4XjgZrku5jjgZHjgovjgZPjgajvvIEgICAgKi8KCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxtYXRoLmg+CgpzdGF0aWMgaW50IFNpbkNvc19udW09LTE7CnN0YXRpYyBkb3VibGUgKlNpbkNvc190YWJsZT1OVUxMOwoKLyojaW5jbHVkZSAic2luY29zX3RhYmxlLmgiKi8KCi8qIFNpbkNvc19pbml0OiDvvJnvvJDluqbliIbjga4gY29zKCkg44OG44O844OW44Or44KS5L2c5oiQ44GZ44KLICovCnZvaWQgU2luQ29zX2luaXQoaW50IG51bSkKewogICAgaW50IGk7CgogICAgaWYgKG51bTw9MCkgewogICAgICAgIGZwcmludGYoc3RkZXJyLCAiU2luQ29zOiBzcGVjaWZpZWQgaW5pdCBudW1iZXIgZXJyb3IgKCVkKS5cbiIsIG51bSk7CiAgICAgICAgZXhpdCgxKTsKICAgIH0KICAgIFNpbkNvc190YWJsZT1tYWxsb2Moc2l6ZW9mKGRvdWJsZSkqbnVtKTsKICAgIGlmIChTaW5Db3NfdGFibGU9PU5VTEwpIHsKICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlNpbkNvczogbm90IGVub3VnaCBtZW1vcnkuXG4iKTsKICAgICAgICBleGl0KDEpOwogICAgfQogICAgU2luQ29zX251bT1udW07CiAgICBmb3IgKGk9MDsgaTxudW07IGkrKykgewogICAgICAgIFNpbkNvc190YWJsZVtpXT1jb3MoaSpNX1BJLzIvbnVtKTsKICAgIH0KfQoKLyogU2luQ29zIOODhuODvOODluODq+evhOWbsuOCkuavjuWbnuODgeOCp+ODg+OCr++8juWumue+qeOBmeOCi+OBqOWuieWFqOOBoOOBjO+8ku+8kOWAjeOBr+mBheOBj+OBquOCiyAqLwojdW5kZWYgU0lOQ09TX0NIRUNLCgovKiBDb3MoKSDplqLmlbAgKi8KZG91YmxlIENvcyhkb3VibGUgeCkKewogICAgZG91YmxlIHNpZ249MTsKICAgIGludCBpOwoKI2lmZGVmIFNJTkNPU19DSEVDSwogICAgaWYgKFNpbkNvc19udW08PTApIHsKICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIk5vdCBpbml0aWFsaXplIFNpbkNvc190YWJsZS5cbiIpOwogICAgICAgIGV4aXQoMSk7CiAgICB9CiNlbmRpZgogICAgaWYgKHg8MCkgeD0teDsgICAgICAgICAgICAgIC8qICBjb3MoeCk9Y29zKC14KSAgICAgKi8KICAgIHgvPU1fUEk7CiAgICB4PSh4LShpbnQpKHgvMikqMik7ICAgICAgICAgLyogIGNvcyh4KT1jb3MoeCsyKlBJKSAqLwogICAgaWYgKHg+MSkgeD0yLXg7ICAgICAgICAgICAgIC8qICBjb3MoeCk9Y29zKHgtUEkpICAgKi8KICAgIGlmICh4Pi41KSB7eD0xLXg7IHNpZ249LTE7fSAvKiAtY29zKHgpPWNvcyhQSS14KSAgICovCiAgICBpPShpbnQpKHgqMipTaW5Db3NfbnVtKTsKI2lmZGVmIFNJTkNPU19DSEVDSwogICAgaWYgKGk8MCB8fCBpPj1TaW5Db3NfbnVtKSB7CiAgICBmcHJpbnRmKHN0ZGVyciwgIlNpbkNvczogc3BlY2lmaWVkIG51bWJlciBvdXQgb2YgcmFuZ2UgKCVkKS5cbiIsIGkpOwogICAgZXhpdCgxKTsKICAgIH0KI2VuZGlmCiAgICByZXR1cm4gKHNpZ24qU2luQ29zX3RhYmxlW2ldKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qI2lmZGVmIFNJTkNPU19UQUJMRV9URVNUKi8KI2luY2x1ZGUgPHRpbWUuaD4KCmludCBtYWluKHZvaWQpCnsKICAgIGludCBpLCBqLCBudW07CiAgICBjbG9ja190IHQ7CiAgICBkb3VibGUgeCA9IDA7CgogICAgLyogU2luQ29z44OG44O844OW44Or5Yid5pyf5YyWICovCiAgICAvKiDliIblibLmlbDjgajoqqTlt67jga7nm67lrok6IOWIhuWJsuaVsCAxZStYLCDoqqTlt64gMWUtKFgrMSkgKi8KICAgIG51bT0xZSs1OwogICAgU2luQ29zX2luaXQobnVtKTsKICAgIHByaW50ZigiU2luQ29zX1RhYmxlOiVkXG4iLCBudW0pOwojaWYgMAogICAgLyogMC4wMSBbcmFkXSDliLvjgb/jgacgc2luKCkg44GoIFNpbigpLCBjb3MoKSDjgaggQ29zKCkg44Gu57K+5bqm5q+U6LyD44KS44GZ44KLICovCiAgICBwcmludGYoIngsc2luKCksU2luKCksc2luKCktU2luKHgpXG4iKTsKICAgIGZvciAoeD0tMTA7IHg8MTA7IHgrPTAuMDEpIHsKICAgICAgICBwcmludGYoIiVmICVmICVmICUrZVxuIiwgeCwgc2luKHgpLCBTaW4oeCksIHNpbih4KS1TaW4oeCkpOwogICAgfQogICAgcHJpbnRmKCJcbiIpOwogICAgcHJpbnRmKCJ4LGNvcygpLENvcygpLGNvcygpLUNvcyh4KVxuIik7CiAgICBmb3IgKHg9LTEwOyB4PDEwOyB4Kz0wLjAxKSB7CiAgICAgICAgcHJpbnRmKCIlZiAlZiAlZiAlK2VcbiIsIHgsIGNvcyh4KSwgQ29zKHgpLCBjb3MoeCktQ29zKHgpKTsKICAgIH0KICAgIHByaW50ZigiXG4iKTsKI2VuZGlmCgogICAgLyogY29zKCkg44GoIENvcygpIOOBrumAn+W6puavlOi8gyAqLwogICAgcHJpbnRmKCJUaW1lIGJlbmNobWFyazogY29zKCksIENvcygpXG4iKTsKICAgIC8qIGNvcygpICovCiAgICB0PWNsb2NrKCk7CiAgICBmb3IgKGk9MDsgaTw1MDAwMDsgaSsrKQogICAgICAgIGZvciAoaj0wOyBqPDEwMDAwOyBqKyspCiAgICAgICAgICAgIHggKz0gY29zKC4xKTsKICAgIHByaW50ZigiY29zOiUuMmZzZWNcbiIsIChkb3VibGUpKGNsb2NrKCktdCkgLyBDTE9DS1NfUEVSX1NFQyk7CgogICAgLyogQ29zKCkgKi8KICAgIHQ9Y2xvY2soKTsKICAgIGZvciAoaT0wOyBpPDUwMDAwOyBpKyspCiAgICBmb3IgKGo9MDsgajwxMDAwMDsgaisrKQogICAgICAgIHggKz0gQ29zKC4xKTsKICAgIHByaW50ZigiQ29zOiUuMmZzZWNcbiIsIChkb3VibGUpKGNsb2NrKCktdCkgLyBDTE9DS1NfUEVSX1NFQyk7CiAgICByZXR1cm4gKGludCl4Owp9Ci8qI2VuZGlmIC8qIFNJTkNPU19UQUJMRV9URVNUICovCg==