summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorenge <enge@211d60ee-9f03-0410-a15a-8952a2c7a4e4>2011-01-07 20:02:45 +0000
committerenge <enge@211d60ee-9f03-0410-a15a-8952a2c7a4e4>2011-01-07 20:02:45 +0000
commita0a24dd6f60dbcaf09942807f86259d9f1ca16f9 (patch)
tree0a4a590505d4dc948f699e846fd26a19ba7cb9a5
parente7819e979c2d86ecbcd411ccd2b66834257c7abb (diff)
downloadmpc-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--NEWS6
-rw-r--r--TODO6
-rw-r--r--src/tan.c24
3 files changed, 14 insertions, 22 deletions
diff --git a/NEWS b/NEWS
index 95fe789..21b98cc 100644
--- a/NEWS
+++ b/NEWS
@@ -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
diff --git a/TODO b/TODO
index 84620bc..a6abca2 100644
--- a/TODO
+++ b/TODO
@@ -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
diff --git a/src/tan.c b/src/tan.c
index d730a06..5301128 100644
--- a/src/tan.c
+++ b/src/tan.c
@@ -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));