r4064 - trunk/bse



Author: timj
Date: 2006-11-04 13:47:17 -0500 (Sat, 04 Nov 2006)
New Revision: 4064

Modified:
   trunk/bse/ChangeLog
   trunk/bse/bsefilter-ellf.c
   trunk/bse/bsemath.h
Log:
Sat Nov  4 19:46:01 2006  Tim Janik  <timj gtk org>                                                                                                           
                                                                                                                                                              
        * bsefilter-ellf.c: replaced all ellf specific complex number                                                                                         
        arithmetic by bse_complex*() calls.                                                                                                                   
                                                                                                                                                              
        * bsemath.h: provide BSE_COMPLEX_ONE for convenience.                                                                                                 
                                                                                                                                                              



Modified: trunk/bse/ChangeLog
===================================================================
--- trunk/bse/ChangeLog	2006-11-04 17:15:02 UTC (rev 4063)
+++ trunk/bse/ChangeLog	2006-11-04 18:47:17 UTC (rev 4064)
@@ -1,3 +1,10 @@
+Sat Nov  4 19:46:01 2006  Tim Janik  <timj gtk org>
+
+	* bsefilter-ellf.c: replaced all ellf specific complex number 
+	arithmetic by bse_complex*() calls.
+
+	* bsemath.h: provide BSE_COMPLEX_ONE for convenience.
+
 Sat Nov  4 18:14:08 2006  Tim Janik  <timj gtk org>
 
 	* gslmathtest.c: removed, this has been ported to bsemathtest and

Modified: trunk/bse/bsefilter-ellf.c
===================================================================
--- trunk/bse/bsefilter-ellf.c	2006-11-04 17:15:02 UTC (rev 4063)
+++ trunk/bse/bsefilter-ellf.c	2006-11-04 18:47:17 UTC (rev 4064)
@@ -327,14 +327,6 @@
  */
 
 /* --- prototypes --- */
-static const BseComplex COMPLEX_ONE = {1.0, 0.0};
-static double Cabs   (const BseComplex *z);
-static void   Cadd   (const BseComplex *a, const BseComplex *b, BseComplex *c);
-static void   Cdiv   (const BseComplex *a, const BseComplex *b, BseComplex *c);
-static void   Cmov   (const BseComplex *a,                   BseComplex *b);
-static void   Cmul   (const BseComplex *a, const BseComplex *b, BseComplex *c);
-static void   Csqrt  (const BseComplex *z,                   BseComplex *w);
-static void   Csub   (const BseComplex *a, const BseComplex *b, BseComplex *c);
 static double polevl (double x, const double coef[], int N);
 static double ellik  (double phi, double m); // incomplete elliptic integral of the first kind
 static double ellpk  (double x); // complete elliptic integral of the first kind
@@ -421,269 +413,6 @@
   return 0;
 }
 
-/* --- complex number arithmetic --- */
-/* c = b + a	*/
-static void
-Cadd (const BseComplex *a, const BseComplex *b, BseComplex *c)
-{
-  c->re = b->re + a->re;
-  c->im = b->im + a->im;
-}
-
-/* c = b - a	*/
-static void
-Csub (const BseComplex *a, const BseComplex *b, BseComplex *c)
-{
-  c->re = b->re - a->re;
-  c->im = b->im - a->im;
-}
-
-/* c = b * a */
-static void
-Cmul (const BseComplex *a, const BseComplex *b, BseComplex *c)
-{
-  /* Multiplication:
-   *    c.re  =  b.re * a.re  -  b.im * a.im
-   *    c.im  =  b.re * a.im  +  b.im * a.re
-   */
-  double y;
-  y    = b->re * a->re  -  b->im * a->im;
-  c->im = b->re * a->im  +  b->im * a->re;
-  c->re = y;
-  /* see Cdiv() for accuracy comments */
-}
-
-/* c = b / a */
-static void
-Cdiv (const BseComplex *a, const BseComplex *b, BseComplex *c)
-{
-  /* Division:
-   *    d    =  a.re * a.re  +  a.im * a.im
-   *    c.re  = (b.re * a.re  + b.im * a.im)/d
-   *    c.im  = (b.im * a.re  -  b.re * a.im)/d
-   */
-  double y = a->re * a->re  +  a->im * a->im;
-  double p = b->re * a->re  +  b->im * a->im;
-  double q = b->im * a->re  -  b->re * a->im;
-  
-  if (y < 1.0)
-    {
-      double w = MAXNUM * y;
-      if ((fabs (p) > w) || (fabs (q) > w) || (y == 0.0))
-        {
-          c->re = MAXNUM;
-          c->im = MAXNUM;
-          math_set_error ("Cdiv", MATH_ERROR_OVERFLOW);
-          return;
-        }
-    }
-  c->re = p/y;
-  c->im = q/y;
-  /* ACCURACY:
-   * In DEC arithmetic, the test (1/z) * z = 1 had peak relative
-   * error 3.1e-17, rms 1.2e-17.  The test (y/z) * (z/y) = 1 had
-   * peak relative error 8.3e-17, rms 2.1e-17.
-   * Tests in the rectangle {-10,+10}:
-   *                      Relative error:
-   * arithmetic   function  # trials      peak         rms
-   *    DEC        Cadd       10000       1.4e-17     3.4e-18
-   *    IEEE       Cadd      100000       1.1e-16     2.7e-17
-   *    DEC        Csub       10000       1.4e-17     4.5e-18
-   *    IEEE       Csub      100000       1.1e-16     3.4e-17
-   *    DEC        Cmul        3000       2.3e-17     8.7e-18
-   *    IEEE       Cmul      100000       2.1e-16     6.9e-17
-   *    DEC        Cdiv       18000       4.9e-17     1.3e-17
-   *    IEEE       Cdiv      100000       3.7e-16     1.1e-16
-   */
-}
-
-/* b = a */
-static void
-Cmov (const BseComplex *a, BseComplex *b)
-{
-  *b = *a;
-}
-
-/* Cabs() - Complex absolute value
- *
- * SYNOPSIS:
- * double Cabs();
- * BseComplex z;
- * double a;
- *
- * a = Cabs (&z);
- *
- * DESCRIPTION:
- * If z = x + iy
- * then
- *       a = sqrt (x**2 + y**2).
- * Overflow and underflow are avoided by testing the magnitudes
- * of x and y before squaring.  If either is outside half of
- * the floating point full scale range, both are rescaled.
- *
- * ACCURACY:
- *                      Relative error:
- * arithmetic   domain     # trials      peak         rms
- *    DEC       -30,+30     30000       3.2e-17     9.2e-18
- *    IEEE      -10,+10    100000       2.7e-16     6.9e-17
- */
-static double
-Cabs (const BseComplex *z)
-{
-  /* exponent thresholds for IEEE doubles */
-  const double PREC = 27;
-  const double MAXEXP = 1024;
-  const double MINEXP = -1077;
-
-  double x, y, b, re, im;
-  int ex, ey, e;
-  
-  /* Note, Cabs (INFINITY,NAN) = INFINITY. */
-  if (z->re == INFINITY || z->im == INFINITY
-      || z->re == -INFINITY || z->im == -INFINITY)
-    return INFINITY;
-  
-  if (isnan (z->re))
-    return z->re;
-  if (isnan (z->im))
-    return z->im;
-  
-  re = fabs (z->re);
-  im = fabs (z->im);
-  
-  if (re == 0.0)
-    return im;
-  if (im == 0.0)
-    return re;
-  
-  /* Get the exponents of the numbers */
-  x = frexp (re, &ex);
-  y = frexp (im, &ey);
-  
-  /* Check if one number is tiny compared to the other */
-  e = ex - ey;
-  if (e > PREC)
-    return re;
-  if (e < -PREC)
-    return im;
-  
-  /* Find approximate exponent e of the geometric mean. */
-  e = (ex + ey) >> 1;
-  
-  /* Rescale so mean is about 1 */
-  x = ldexp (re, -e);
-  y = ldexp (im, -e);
-  
-  /* Hypotenuse of the right triangle */
-  b = sqrt (x * x  +  y * y);
-  
-  /* Compute the exponent of the answer. */
-  y = frexp (b, &ey);
-  ey = e + ey;
-  
-  /* Check it for overflow and underflow. */
-  if (ey > MAXEXP)
-    {
-      math_set_error ("Cabs", MATH_ERROR_OVERFLOW);
-      return INFINITY;
-    }
-  if (ey < MINEXP)
-    return 0.0;
-  
-  /* Undo the scaling */
-  b = ldexp (b, e);
-  return b;
-}
-
-/* Csqrt() - Complex square root
- *
- * SYNOPSIS:
- * void Csqrt();
- * BseComplex z, w;
- * Csqrt (&z, &w);
- *
- * DESCRIPTION:
- * If z = x + iy,  r = |z|, then
- *                       1/2
- * Im w  =  [ (r - x)/2 ]   ,
- * Re w  =  y / 2 Im w.
- *
- * Note that -w is also a square root of z.  The root chosen
- * is always in the upper half plane.
- * Because of the potential for cancellation error in r - x,
- * the result is sharpened by doing a Heron iteration
- * (see sqrt.c) in complex arithmetic.
- *
- * ACCURACY:
- *                      Relative error:
- * arithmetic   domain     # trials      peak         rms
- *    DEC       -10,+10     25000       3.2e-17     9.6e-18
- *    IEEE      -10,+10    100000       3.2e-16     7.7e-17
- *                        2
- * Also tested by Csqrt (z) = z, and tested by arguments
- * close to the real axis.
- */
-static void
-Csqrt (const BseComplex *z, BseComplex *w)
-{
-  BseComplex q, s;
-  double x, y, r, t;
-  
-  x = z->re;
-  y = z->im;
-  
-  if (y == 0.0)
-    {
-      if (x < 0.0)
-        {
-          w->re = 0.0;
-          w->im = sqrt (-x);
-          return;
-        }
-      else
-        {
-          w->re = sqrt (x);
-          w->im = 0.0;
-          return;
-        }
-    }
-  
-  if (x == 0.0)
-    {
-      r = fabs (y);
-      r = sqrt (0.5*r);
-      if (y > 0)
-        w->re = r;
-      else
-        w->re = -r;
-      w->im = r;
-      return;
-    }
-  
-  /* Approximate  sqrt (x^2+y^2) - x  =  y^2/2x - y^4/24x^3 + ... .
-   * The relative error in the first term is approximately y^2/12x^2 .
-   */
-  if ((fabs (y) < 2.e-4 * fabs (x))
-      && (x > 0))
-    {
-      t = 0.25*y*(y/x);
-    }
-  else
-    {
-      r = Cabs (z);
-      t = 0.5*(r - x);
-    }
-  
-  r = sqrt (t);
-  q.im = r;
-  q.re = y/(2.0*r);
-  /* Heron iteration in complex arithmetic */
-  Cdiv (&q, z, &s);
-  Cadd (&q, &s, w);
-  w->re *= 0.5;
-  w->im *= 0.5;
-}
-
 /* --- elliptic functions --- */
 /* ellik.c - Incomplete elliptic integral of the first kind
  *
@@ -1384,7 +1113,7 @@
               cden.re = 1 - C * r.re;
               cden.im = -C * r.im;
               ds->z_counter += 1;
-              Cdiv (&cden, &cnum, &z_pz[ds->z_counter]);
+              z_pz[ds->z_counter] = bse_complex_div (cnum, cden);
               if (r.im != 0.0)
                 {
                   /* fill in complex conjugate root */
@@ -1412,25 +1141,25 @@
               else
                 cwc.re = ds->tan_angle_frequency;
               cwc.im = 0.0;
-              Cmul (&r, &cwc, &cnum);     /* r wc */
-              Csub (&cnum, &COMPLEX_ONE, &ca);   /* a = 1 - r wc */
-              Cmul (&cnum, &cnum, &b4ac); /* 1 - (r wc)^2 */
-              Csub (&b4ac, &COMPLEX_ONE, &b4ac);
+              cnum = bse_complex_mul (r, cwc);
+              ca = bse_complex_sub (BSE_COMPLEX_ONE, cnum);   /* a = 1 - r wc */
+              b4ac = bse_complex_mul (cnum, cnum); /* 1 - (r wc)^2 */
+              b4ac = bse_complex_sub (BSE_COMPLEX_ONE, b4ac);
               b4ac.re *= 4.0;               /* 4ac */
               b4ac.im *= 4.0;
               cb.re = -2.0 * ds->cgam;          /* b */
               cb.im = 0.0;
-              Cmul (&cb, &cb, &cnum);     /* b^2 */
-              Csub (&b4ac, &cnum, &b4ac); /* b^2 - 4 ac */
-              Csqrt (&b4ac, &b4ac);
+              cnum = bse_complex_mul (cb, cb);     /* b^2 */
+              b4ac = bse_complex_sub (cnum, b4ac); /* b^2 - 4 ac */
+              b4ac = bse_complex_sqrt (b4ac);
               cb.re = -cb.re;  /* -b */
               cb.im = -cb.im;
               ca.re *= 2.0; /* 2a */
               ca.im *= 2.0;
-              Cadd (&b4ac, &cb, &cnum);   /* -b + sqrt(b^2 - 4ac) */
-              Cdiv (&ca, &cnum, &cnum);   /* ... /2a */
+              cnum = bse_complex_add (b4ac, cb);   /* -b + sqrt(b^2 - 4ac) */
+              cnum = bse_complex_div (cnum, ca);
               ds->z_counter += 1;
-              Cmov (&cnum, &z_pz[ds->z_counter]);
+              z_pz[ds->z_counter] = cnum;
               if (cnum.im != 0.0)
                 {
                   ds->z_counter += 1;
@@ -1439,10 +1168,10 @@
                 }
               if ((r.im != 0.0) || (cnum.im == 0))
                 {
-                  Csub (&b4ac, &cb, &cnum);  /* -b - sqrt(b^2 - 4ac) */
-                  Cdiv (&ca, &cnum, &cnum);  /* ... /2a */
+                  cnum = bse_complex_sub (cb, b4ac);  /* -b - sqrt(b^2 - 4ac) */
+                  cnum = bse_complex_div (cnum, ca);  /* ... /2a */
                   ds->z_counter += 1;
-                  Cmov (&cnum, &z_pz[ds->z_counter]);
+                  z_pz[ds->z_counter] = cnum;
                   if (cnum.im != 0.0)
                     {
                       ds->z_counter += 1;
@@ -1747,15 +1476,15 @@
   den.im = 0.0;
   for (j = 0; j < ds->n_solved_poles; j++)
     {
-      Csub (&ds->zcpz[j], &x, &w);
-      Cmul (&w, &den, &den);
-      Csub (&ds->zcpz[ds->n_solved_poles + j], &x, &w);
-      Cmul (&w, &num, &num);
+      w = bse_complex_sub (x, ds->zcpz[j]);
+      den = bse_complex_mul (w, den);
+      w = bse_complex_sub (x, ds->zcpz[ds->n_solved_poles + j]);
+      num = bse_complex_mul (w, num);
     }
-  Cdiv (&den, &num, &w);
+  w = bse_complex_div (num, den);
   w.re *= amp;
   w.im *= amp;
-  u = Cabs (&w);
+  u = bse_complex_abs (w);
   return u;
 }
 

Modified: trunk/bse/bsemath.h
===================================================================
--- trunk/bse/bsemath.h	2006-11-04 17:15:02 UTC (rev 4063)
+++ trunk/bse/bsemath.h	2006-11-04 18:47:17 UTC (rev 4064)
@@ -47,6 +47,7 @@
 #define BSE_LN_2_POW_1_DIV_1200_d     (5.776226504666210911810267678818138067296e-4) // ln(2^(1/1200))
 #define BSE_2_POW_1_DIV_72            (1.009673533228510862192521401118605073603)    // 2^(1/72)
 #define BSE_LN_2_POW_1_DIV_72         (9.62704417444368485301711279803023011216e-3)  // ln(2^(1/72))
+#define BSE_COMPLEX_ONE               (bse_complex (1, 0))
 
 /* --- structures --- */
 typedef struct {




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]