ciabatta/src/math/gen_math.h

229 lines
5.6 KiB
C

static ftype suffix(cordic)(
ftype x0, // x initial value
ftype y0, // y initial value
ftype z0, // initial 'angle'
int m, // system: 1 for trig, -1 for hyperbolic
int v, // mode: 1 for vectoring, 0 for rotation
ftype *c, // output x
ftype *s // output y
) {
int tab_count = 0;
ftype *tab = NULL;
if(m == 1) {
tab = suffix(ttable);
tab_count = countof(suffix(ttable));
}
else if(m == -1) {
tab = suffix(htable);
tab_count = countof(suffix(htable));
}
ftype x = x0;
ftype y = y0;
ftype z = z0;
for(int i = 0; i != tab_count; ++i) {
ftype sign;
if(v) sign = (y < 0)? 1 : -1;
else sign = (z < 0)? -1 : 1;
ftype x1 = suffix(fma)(suffix(ptable)[i], -m*sign*y, x);
ftype y1 = suffix(fma)(suffix(ptable)[i], x*sign, y);
x = x1;
y = y1;
z = suffix(fma)(tab[i], -sign, z);
}
if(c!=NULL) *c = x;
if(s!=NULL) *s = y;
return z;
}
ftype suffix(sin)(ftype x) {
if(isinf(x)) return NAN;
if(isnan(x)) return NAN;
int k;
ftype alpha = suffix(remquo)(x, HALF_PI, &k);
if(x == 0) return x;
k = (((k % 4) +4) %4);
ftype sinx;
ftype cosx;
suffix(cordic)(suffix(tK), 0, alpha, 1, 0, &cosx, &sinx);
switch(k) {
case 0: return sinx;
case 1: return cosx;
case 2: return -sinx;
case 3: return -cosx;
}
return 0;
}
ftype suffix(cos)(ftype x) {
if(isinf(x)) return NAN;
if(isnan(x)) return NAN;
int k;
ftype alpha = suffix(remquo)(x, HALF_PI, &k);
k = (((k % 4) +4) %4);
ftype sinx;
ftype cosx;
suffix(cordic)(suffix(tK), 0, alpha, 1, 0, &cosx, &sinx);
switch(k) {
case 0: return cosx;
case 1: return -sinx;
case 2: return -cosx;
case 3: return sinx;
}
return 0;
}
ftype suffix(tan)(ftype x) {
if(isinf(x)) return NAN;
if(isnan(x)) return NAN;
int k;
ftype alpha = suffix(remquo)(x, HALF_PI, &k);
if(x == 0) return x;
k = (((k % 2) +2) %2);
ftype sinx;
ftype cosx;
suffix(cordic)(suffix(tK), 0, alpha, 1, 0, &cosx, &sinx);
switch(k) {
case 0: return sinx/cosx;
case 1: return -cosx/sinx;
}
return 0;
}
ftype suffix(cot)(ftype x) {
if(x == 0) return x;
if(isinf(x)) return NAN;
if(isnan(x)) return NAN;
int k;
ftype alpha = suffix(remquo)(x, HALF_PI, &k);
k = (((k % 2) +2) %2);
ftype sinx;
ftype cosx;
suffix(cordic)(suffix(tK), 0, alpha, 1, 0, &cosx, &sinx);
switch(k) {
case 0: return cosx/sinx;
case 1: return -sinx/cosx;
}
return 0;
}
ftype suffix(exp)(ftype x) {
if(x == 0) return x;
if(isinf(x)) return NAN;
if(isnan(x)) return NAN;
ftype t = x*LOG2E;
int64_t k = (int64_t)t;
x = (t - (ftype)k) / LOG2E;
ftype xx = x*x;
ftype xxx = xx*x;
ftype xxxx = xx*xx;
ftype xxxxx = xxx*xx;
ftype expx = 1+x + xx/2.0 + xxx/6.0+ xxxx/24.0 + xxxxx/720.0;
if(k>0) expx *= 2.0;
if(k>0) while(k-- > 0) expx *= 2.0;
if(k<0) while(k++ < 0) expx /= 2.0;
return expx;
}
ftype suffix(atan)(ftype x) {
if(x == 0) return x;
if(isinf(x)) return INFINITY;
if(isnan(x)) return NAN;
ftype atan;
if(x > 1) {
atan = HALF_PI - suffix(cordic)(x, 1, 0, 1, 1, NULL, NULL);
}
else if(x < -1) {
atan = -HALF_PI + suffix(cordic)(-x, 1, 0, 1, 1, NULL, NULL);
}
else {
atan = suffix(cordic)(1, x, 0, 1, 1, NULL, NULL);
}
return atan;
}
ftype suffix(acos)(ftype x) {
if(x == 0) return HALF_PI;
if(x == -1) return PI;
if(x == 1) return 0;
if(isinf(x)) return INFINITY;
if(isnan(x)) return NAN;
if(fabs(x) > 1) return NAN;
ftype atan;
x = sqrt(fma(-x,x,1))/x;
if(x > 1) {
atan = HALF_PI - suffix(cordic)(x, 1, 0, 1, 1, NULL, NULL);
}
else if(x < -1) {
atan = -HALF_PI + suffix(cordic)(-x, 1, 0, 1, 1, NULL, NULL);
}
else {
atan = suffix(cordic)(1, x, 0, 1, 1, NULL, NULL);
}
if(x < 0) atan += PI;
return atan;
}
ftype suffix(asin)(ftype x) {
if(x == 0) return 0;
if(x == -1) return -HALF_PI;
if(x == 1) return HALF_PI;
if(isinf(x)) return INFINITY;
if(isnan(x)) return NAN;
if(fabs(x) > 1) return NAN;
ftype atan;
x /= sqrt(fma(-x,x,1));
if(x > 1) {
atan = HALF_PI - suffix(cordic)(x, 1, 0, 1, 1, NULL, NULL);
}
else if(x < -1) {
atan = -HALF_PI + suffix(cordic)(-x, 1, 0, 1, 1, NULL, NULL);
}
else {
atan = suffix(cordic)(1, x, 0, 1, 1, NULL, NULL);
}
return atan;
}
// ftype suffix(exp)(ftype x) {
// if(isnan(x)) return NAN;
// if(x > 0 && isinf(x)) return +INFINITY;
// if(x < 0 && isinf(x)) return +0.0;
// if(x == 0) return 1.0;
// if(x > 709.8) {
// #if math_errhandling & MATH_ERREXCEPT
// feraiseexcept(FE_OVERFLOW);
// #endif
// #if math_errhandling & MATH_ERRNO
// errno = ERANGE;
// #endif
// return +INFINITY;
// }
// if(x < -708.4) {
// #if math_errhandling & MATH_ERREXCEPT
// feraiseexcept(FE_OVERFLOW);
// #endif
// #if math_errhandling & MATH_ERRNO
// errno = ERANGE;
// #endif
// return 0;
// }
// ftype e = 1.0;
// ftype xp = 1.0;
// ftype f = 1;
// for(uint64_t i = 1; i != 10; ++i) {
// f *= i;
// xp *= x;
// e += xp / f;
// }
// return e;
// }
ftype suffix(exp2)(ftype x) {
return suffix(exp)(x * LN2);
}
ftype suffix(expm1)(ftype x) {
return suffix(exp)(x) - 1.0;
}