mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Optimize sin/cos
GCC/Clang can optimize to calculate `sin(x)` and `cos(x)` at once, when the both are closely called on the same argument. Similar optimization is possible for `__sinpi(x)` and `__cospi(x)` if available, which calculate arguments in radian, i.e. `sin(x*M_PI)` and `cos(x*M_PI)` respectively.
This commit is contained in:
parent
8af098b40e
commit
e49ecaed57
2 changed files with 17 additions and 4 deletions
19
complex.c
19
complex.c
|
@ -661,8 +661,9 @@ f_complex_polar(VALUE klass, VALUE x, VALUE y)
|
||||||
y = DBL2NUM(imag);
|
y = DBL2NUM(imag);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
y = f_mul(x, DBL2NUM(sin(arg)));
|
const double ax = sin(arg), ay = cos(arg);
|
||||||
x = f_mul(x, DBL2NUM(cos(arg)));
|
y = f_mul(x, DBL2NUM(ax));
|
||||||
|
x = f_mul(x, DBL2NUM(ay));
|
||||||
if (canonicalization && f_zero_p(y)) return x;
|
if (canonicalization && f_zero_p(y)) return x;
|
||||||
}
|
}
|
||||||
return nucomp_s_new_internal(klass, x, y);
|
return nucomp_s_new_internal(klass, x, y);
|
||||||
|
@ -672,6 +673,16 @@ f_complex_polar(VALUE klass, VALUE x, VALUE y)
|
||||||
f_mul(x, m_sin(y)));
|
f_mul(x, m_sin(y)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE___COSPI
|
||||||
|
# define cospi(x) __cospi(x)
|
||||||
|
#else
|
||||||
|
# define cospi(x) cos((x) * M_PI)
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE___SINPI
|
||||||
|
# define sinpi(x) __sinpi(x)
|
||||||
|
#else
|
||||||
|
# define sinpi(x) sin((x) * M_PI)
|
||||||
|
#endif
|
||||||
/* returns a Complex or Float of ang*PI-rotated abs */
|
/* returns a Complex or Float of ang*PI-rotated abs */
|
||||||
VALUE
|
VALUE
|
||||||
rb_dbl_complex_new_polar_pi(double abs, double ang)
|
rb_dbl_complex_new_polar_pi(double abs, double ang)
|
||||||
|
@ -689,8 +700,8 @@ rb_dbl_complex_new_polar_pi(double abs, double ang)
|
||||||
return DBL2NUM(abs);
|
return DBL2NUM(abs);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ang *= M_PI;
|
const double real = abs * cospi(ang), imag = abs * sinpi(ang);
|
||||||
return rb_complex_new(DBL2NUM(abs * cos(ang)), DBL2NUM(abs * sin(ang)));
|
return rb_complex_new(DBL2NUM(real), DBL2NUM(imag));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1991,6 +1991,8 @@ AC_CHECK_FUNCS(utimensat)
|
||||||
AC_CHECK_FUNCS(utimes)
|
AC_CHECK_FUNCS(utimes)
|
||||||
AC_CHECK_FUNCS(wait4)
|
AC_CHECK_FUNCS(wait4)
|
||||||
AC_CHECK_FUNCS(waitpid)
|
AC_CHECK_FUNCS(waitpid)
|
||||||
|
AC_CHECK_FUNCS(__cospi)
|
||||||
|
AC_CHECK_FUNCS(__sinpi)
|
||||||
|
|
||||||
AS_IF([test "x$ac_cv_member_struct_statx_stx_btime" = xyes],
|
AS_IF([test "x$ac_cv_member_struct_statx_stx_btime" = xyes],
|
||||||
[AC_CHECK_FUNCS(statx)])
|
[AC_CHECK_FUNCS(statx)])
|
||||||
|
|
Loading…
Reference in a new issue