diff options
author | enge <enge@211d60ee-9f03-0410-a15a-8952a2c7a4e4> | 2011-01-07 20:02:45 +0000 |
---|---|---|
committer | enge <enge@211d60ee-9f03-0410-a15a-8952a2c7a4e4> | 2011-01-07 20:02:45 +0000 |
commit | a0a24dd6f60dbcaf09942807f86259d9f1ca16f9 (patch) | |
tree | 0a4a590505d4dc948f699e846fd26a19ba7cb9a5 | |
parent | e7819e979c2d86ecbcd411ccd2b66834257c7abb (diff) | |
download | mpc-a0a24dd6f60dbcaf09942807f86259d9f1ca16f9.tar.gz |
tan: use sin_cos, gains about a third of the running time in ttan
git-svn-id: svn://scm.gforge.inria.fr/svn/mpc/trunk@862 211d60ee-9f03-0410-a15a-8952a2c7a4e4
-rw-r--r-- | NEWS | 6 | ||||
-rw-r--r-- | TODO | 6 | ||||
-rw-r--r-- | src/tan.c | 24 |
3 files changed, 14 insertions, 22 deletions
@@ -4,8 +4,10 @@ Changes in version 0.8.3: between mpc type variables and C variables of type double _Complex or long double _Complex - mpc_sin_cos, computing simultaneously the sine and cosine - - Speed-up of mpc_pow_si through binary exponentiation, and of - mpc_pow_z when the exponent fits in a long + - Speed-ups: + - mpc_pow_si through binary exponentiation + - mpc_pow_z when the exponent fits in a long + - mpc_tan through the use of mpc_sin_cos - Bug fixes: - trigonometric functions: infinite loop due to overflow for large arguments - exp: close to infinite loop for argument close to 0 @@ -3,13 +3,7 @@ Bench: Scripts and web page comparing timings with different systems, as done for mpfr at http://www.mpfr.org/mpfr-2.4.0/timings.html -Efficiency: -- from Andreas Enge 16 September 2008: - Once mpc_sin_cos exists, improve mpc_tan to use it - New functions to implement: -- from Andreas Enge 16 September 2008: - mpc_sin_cos (needs mpfr_sinh_cosh) - from Mickael Gastineau <gastineau@imcce.fr> 14 Apr 2008: mpc_fma: d=a*b+c - from Andreas Enge and Philippe Théveny 17 July 2008 @@ -1,6 +1,6 @@ /* mpc_tan -- tangent of a complex number. -Copyright (C) 2008, 2009, 2010 Philippe Th\'eveny, Andreas Enge, Paul Zimmermann +Copyright (C) 2008, 2009, 2010, 2011 Philippe Th\'eveny, Andreas Enge, Paul Zimmermann This file is part of the MPC Library. @@ -183,7 +183,6 @@ mpc_tan (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd) do { mpfr_exp_t k, exr, eyr, eyi, ezr; - int isinf = 0; ok = 0; @@ -195,23 +194,19 @@ mpc_tan (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd) /* rounding away from zero: except in the cases x=0 or y=0 (processed above), sin x and cos y are never exact, so rounding away from 0 is rounding towards 0 and adding one ulp to the absolute value */ - mpc_sin (x, op, MPC_RNDZZ); - isinf = mpfr_inf_p (MPC_RE (x)) || mpfr_inf_p (MPC_IM (x)); - /* if the real or imaginary part of x is infinite, it means that Im(op) - was large, in which case the result is - sign(tan(Re(op)))*0 + sign(Im(op))*I, - where sign(tan(Re(op))) = sign(Re(x))*sign(Re(y)) */ + mpc_sin_cos (x, y, op, MPC_RNDZZ, MPC_RNDZZ); MPFR_ADD_ONE_ULP (MPC_RE (x)); MPFR_ADD_ONE_ULP (MPC_IM (x)); - MPC_ASSERT (mpfr_zero_p (MPC_RE (x)) == 0); - exr = mpfr_get_exp (MPC_RE (x)); - mpc_cos (y, op, MPC_RNDZZ); - isinf = isinf || mpfr_inf_p (MPC_RE (y)) || mpfr_inf_p (MPC_IM (y)); MPFR_ADD_ONE_ULP (MPC_RE (y)); MPFR_ADD_ONE_ULP (MPC_IM (y)); + MPC_ASSERT (mpfr_zero_p (MPC_RE (x)) == 0); - if (isinf) - { + if ( mpfr_inf_p (MPC_RE (x)) || mpfr_inf_p (MPC_IM (x)) + || mpfr_inf_p (MPC_RE (y)) || mpfr_inf_p (MPC_IM (y))) { + /* If the real or imaginary part of x is infinite, it means that + Im(op) was large, in which case the result is + sign(tan(Re(op)))*0 + sign(Im(op))*I, + where sign(tan(Re(op))) = sign(Re(x))*sign(Re(y)). */ int inex_re, inex_im; mpfr_set_ui (MPC_RE (rop), 0, GMP_RNDN); if (mpfr_sgn (MPC_RE (x)) * mpfr_sgn (MPC_RE (y)) < 0) @@ -235,6 +230,7 @@ mpc_tan (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd) goto end; } + exr = mpfr_get_exp (MPC_RE (x)); eyr = mpfr_get_exp (MPC_RE (y)); eyi = mpfr_get_exp (MPC_IM (y)); |