[gnumeric] GAMMA: Yet another accuracy tweak.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] GAMMA: Yet another accuracy tweak.
- Date: Thu, 19 Dec 2013 18:14:43 +0000 (UTC)
commit d5fb139f0e11776951ebad0451dcb88a7a6396f3
Author: Morten Welinder <terra gnome org>
Date: Thu Dec 19 13:14:02 2013 -0500
GAMMA: Yet another accuracy tweak.
Also, use go_sinpi etc. from goffice.
ChangeLog | 5 +++
configure.ac | 2 +-
src/numbers.h | 62 +++++++++++++++++++++++++++---------------
src/sf-gamma.c | 14 +++++-----
src/sf-trig.c | 82 --------------------------------------------------------
src/sf-trig.h | 3 --
6 files changed, 53 insertions(+), 115 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index be319a7..6f4afd9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2013-12-19 Morten Welinder <terra gnome org>
+
+ * src/sf-gamma.c (qfactf): Squeeze a few extra bits out of this,
+ especially when |x|<1.
+
2013-12-17 Morten Welinder <terra gnome org>
* src/sf-gamma.c (complex_gamma): Turn a complex division into a
diff --git a/configure.ac b/configure.ac
index 04048d0..46c7d8b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -152,7 +152,7 @@ PKG_PROG_PKG_CONFIG(0.18)
dnl *****************************
libspreadsheet_reqs="
- libgoffice-${GOFFICE_API_VER} >= 0.10.9
+ libgoffice-${GOFFICE_API_VER} >= 0.10.10
libgsf-1 >= 1.14.24
libxml-2.0 >= 2.4.12
"
diff --git a/src/numbers.h b/src/numbers.h
index 3a74cb4..cc09273 100644
--- a/src/numbers.h
+++ b/src/numbers.h
@@ -44,6 +44,7 @@ typedef long double gnm_float;
#define gnm_atanh atanhl
#define gnm_ceil ceill
#define gnm_cosh coshl
+#define gnm_cospi go_cospil
#define gnm_erf erfl
#define gnm_erfc erfcl
#define gnm_exp expl
@@ -75,10 +76,12 @@ typedef long double gnm_float;
#define gnm_pow2 go_pow2l
#define gnm_render_general go_render_generall
#define gnm_sinh sinhl
+#define gnm_sinpi go_sinpil
#define gnm_sqrt sqrtl
#define gnm_strto go_strtold
#define gnm_sub_epsilon go_sub_epsilonl
#define gnm_tanh tanhl
+#define gnm_tanpi go_tanpil
#ifndef GNM_REDUCES_TRIG_RANGE
#define gnm_sin sinl
#define gnm_cos cosl
@@ -101,24 +104,30 @@ typedef long double gnm_float;
#define GNM_const(_c) _c ## L
#define GnmQuad GOQuadl
-#define gnm_quad_start go_quad_startl
-#define gnm_quad_end go_quad_endl
-#define gnm_quad_init go_quad_initl
-#define gnm_quad_value go_quad_valuel
+#define gnm_quad_acos go_quad_acosl
#define gnm_quad_add go_quad_addl
-#define gnm_quad_sub go_quad_subl
-#define gnm_quad_mul go_quad_mull
+#define gnm_quad_asin go_quad_asinl
+#define gnm_quad_cos go_quad_cosl
+#define gnm_quad_cospi go_quad_cospil
#define gnm_quad_div go_quad_divl
-#define gnm_quad_mul12 go_quad_mul12l
-#define gnm_quad_sqrt go_quad_sqrtl
-#define gnm_quad_pow go_quad_powl
+#define gnm_quad_e go_quad_el
+#define gnm_quad_end go_quad_endl
#define gnm_quad_exp go_quad_expl
#define gnm_quad_expm1 go_quad_expm1l
-#define gnm_quad_zero go_quad_zerol
+#define gnm_quad_init go_quad_initl
+#define gnm_quad_mul go_quad_mull
+#define gnm_quad_mul12 go_quad_mul12l
#define gnm_quad_one go_quad_onel
#define gnm_quad_pi go_quad_pil
-#define gnm_quad_e go_quad_el
+#define gnm_quad_pow go_quad_powl
+#define gnm_quad_sin go_quad_sinl
+#define gnm_quad_sinpi go_quad_sinpil
+#define gnm_quad_sqrt go_quad_sqrtl
#define gnm_quad_sqrt2 go_quad_sqrt2l
+#define gnm_quad_start go_quad_startl
+#define gnm_quad_sub go_quad_subl
+#define gnm_quad_value go_quad_valuel
+#define gnm_quad_zero go_quad_zerol
#define GnmAccumulator GOAccumulatorl
#define gnm_accumulator_start go_accumulator_startl
#define gnm_accumulator_end go_accumulator_endl
@@ -143,6 +152,7 @@ typedef double gnm_float;
#define gnm_atanh atanh
#define gnm_ceil ceil
#define gnm_cosh cosh
+#define gnm_cospi go_cospi
#define gnm_erf erf
#define gnm_erfc erfc
#define gnm_exp exp
@@ -174,10 +184,12 @@ typedef double gnm_float;
#define gnm_pow2 go_pow2
#define gnm_render_general go_render_general
#define gnm_sinh sinh
+#define gnm_sinpi go_sinpi
#define gnm_sqrt sqrt
#define gnm_strto go_strtod
#define gnm_sub_epsilon go_sub_epsilon
#define gnm_tanh tanh
+#define gnm_tanpi go_tanpi
#ifndef GNM_REDUCES_TRIG_RANGE
#define gnm_sin sin
#define gnm_cos cos
@@ -200,24 +212,30 @@ typedef double gnm_float;
#define GNM_const(_c) _c
#define GnmQuad GOQuad
-#define gnm_quad_start go_quad_start
-#define gnm_quad_end go_quad_end
-#define gnm_quad_init go_quad_init
-#define gnm_quad_value go_quad_value
+#define gnm_quad_acos go_quad_acos
#define gnm_quad_add go_quad_add
-#define gnm_quad_sub go_quad_sub
-#define gnm_quad_mul go_quad_mul
+#define gnm_quad_asin go_quad_asin
+#define gnm_quad_cos go_quad_cos
+#define gnm_quad_cospi go_quad_cospi
#define gnm_quad_div go_quad_div
-#define gnm_quad_mul12 go_quad_mul12
-#define gnm_quad_sqrt go_quad_sqrt
-#define gnm_quad_pow go_quad_pow
+#define gnm_quad_e go_quad_e
+#define gnm_quad_end go_quad_end
#define gnm_quad_exp go_quad_exp
#define gnm_quad_expm1 go_quad_expm1
-#define gnm_quad_zero go_quad_zero
+#define gnm_quad_init go_quad_init
+#define gnm_quad_mul go_quad_mul
+#define gnm_quad_mul12 go_quad_mul12
#define gnm_quad_one go_quad_one
#define gnm_quad_pi go_quad_pi
-#define gnm_quad_e go_quad_e
+#define gnm_quad_pow go_quad_pow
+#define gnm_quad_sin go_quad_sin
+#define gnm_quad_sinpi go_quad_sinpi
+#define gnm_quad_sqrt go_quad_sqrt
#define gnm_quad_sqrt2 go_quad_sqrt2
+#define gnm_quad_start go_quad_start
+#define gnm_quad_sub go_quad_sub
+#define gnm_quad_value go_quad_value
+#define gnm_quad_zero go_quad_zero
#define GnmAccumulator GOAccumulator
#define gnm_accumulator_start go_accumulator_start
#define gnm_accumulator_end go_accumulator_end
diff --git a/src/sf-gamma.c b/src/sf-gamma.c
index f03510e..66030c0 100644
--- a/src/sf-gamma.c
+++ b/src/sf-gamma.c
@@ -897,7 +897,8 @@ qfactf (gnm_float x, GnmQuad *mant, int *exp2)
else {
GnmQuad b;
- gnm_quad_init (&b, -gnm_sinpi (x)); /* ? */
+ gnm_quad_init (&b, -x);
+ gnm_quad_sinpi (&b, &b);
gnm_quad_mul (&b, &b, mant);
gnm_quad_div (mant, &gnm_quad_pi, &b);
*exp2 = -*exp2;
@@ -946,7 +947,7 @@ qfactf (gnm_float x, GnmQuad *mant, int *exp2)
if (debug) g_printerr ("G(x+1)=%.20g * 2^%d %s\n", gnm_quad_value (mant), *exp2, res ?
"overflow" : "");
} else {
- GnmQuad s, mFw;
+ GnmQuad s, qx, mFw;
gnm_float w, f;
int eFw;
@@ -958,14 +959,13 @@ qfactf (gnm_float x, GnmQuad *mant, int *exp2)
*/
w = gnm_floor (x + 0.5);
f = x - w;
+ gnm_quad_init (&qx, x);
gnm_quad_init (&s, 1);
- while (x < 20) {
- GnmQuad a;
- x++;
+ while (w < 20) {
+ gnm_quad_add (&qx, &qx, &gnm_quad_one);
w++;
- gnm_quad_init (&a, x);
- gnm_quad_mul (&s, &s, &a);
+ gnm_quad_mul (&s, &s, &qx);
}
if (qfacti ((int)w, &mFw, &eFw)) {
diff --git a/src/sf-trig.c b/src/sf-trig.c
index 93e3d1b..3ad232a 100644
--- a/src/sf-trig.c
+++ b/src/sf-trig.c
@@ -78,88 +78,6 @@ gnm_acoth (gnm_float x)
/* ------------------------------------------------------------------------- */
-/**
- * gnm_sinpi:
- * @x: a number
- *
- * Returns: the sine of Pi times @x, but with less error than doing the
- * multiplication outright.
- */
-gnm_float
-gnm_sinpi (gnm_float x)
-{
- int k;
-
- if (gnm_isnan (x))
- return x;
-
- if (!gnm_finite (x))
- return gnm_nan;
-
- k = (x < 0) ? 2 : 0;
- x = gnm_fmod (gnm_abs (x), 2);
- if (x >= 1) {
- x -= 1;
- k ^= 2;
- }
- if (x >= 0.5) {
- x -= 0.5;
- k += 1;
- }
- if (x == 0) {
- static const gnm_float ys[4] = { 0, 1, -0, -1 };
- return ys[k];
- } else {
- switch (k) {
- default:
- case 0: return +gnm_sin (M_PIgnum * x);
- case 1: return +gnm_cos (M_PIgnum * x);
- case 2: return -gnm_sin (M_PIgnum * x);
- case 3: return -gnm_cos (M_PIgnum * x);
- }
- }
-}
-
-/**
- * gnm_cospi:
- * @x: a number
- *
- * Returns: the cosine of Pi times @x, but with less error than doing the
- * multiplication outright.
- */
-gnm_float
-gnm_cospi (gnm_float x)
-{
- int k = 0;
-
- if (!gnm_finite (x))
- return gnm_nan;
-
- x = gnm_fmod (gnm_abs (x), 2);
- if (x >= 1) {
- x -= 1;
- k ^= 2;
- }
- if (x >= 0.5) {
- x -= 0.5;
- k += 1;
- }
- if (x == 0) {
- static const gnm_float ys[4] = { 1, 0, -1, -0 };
- return ys[k];
- } else {
- switch (k) {
- default:
- case 0: return +gnm_cos (M_PIgnum * x);
- case 1: return -gnm_sin (M_PIgnum * x);
- case 2: return -gnm_cos (M_PIgnum * x);
- case 3: return +gnm_sin (M_PIgnum * x);
- }
- }
-}
-
-/* ------------------------------------------------------------------------- */
-
#ifdef GNM_REDUCES_TRIG_RANGE
diff --git a/src/sf-trig.h b/src/sf-trig.h
index c9ad770..fb1c72c 100644
--- a/src/sf-trig.h
+++ b/src/sf-trig.h
@@ -8,9 +8,6 @@ gnm_float gnm_acot (gnm_float x);
gnm_float gnm_coth (gnm_float x);
gnm_float gnm_acoth (gnm_float x);
-gnm_float gnm_sinpi (gnm_float x);
-gnm_float gnm_cospi (gnm_float x);
-
#ifdef GNM_REDUCES_TRIG_RANGE
/* gnm_sin, gnm_cos, gnm_tan prototyped in numbers.h */
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]