This is the mail archive of the gsl-discuss@sources.redhat.com mailing list for the GSL project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

periodic cspline first derivative discontinuity



Hello,

I've found a bug (or I think I've found a bug ;-)
in periodic cubic spline implementation -- its
first derivative is not continuous at the edges of
the first segment.

This is because length of next segment (h_ip1
in the patch below) is computed modulo even for
the last segment and so it results as negative
(well, not much clearly explained, perhaps the
patch itself is clearer).

Please note applying this patch actually fixes
only first derivative discontinuity in right edge
of the first segment, some dicontinuity may still
appear at the left edge due to probems in cyclic
tridiagonal linear system solver -- see my next
bugreport.

Yeti

--- gsl-1.1.1.orig/interpolation/cspline.c	Sun Mar 31 19:32:20 2002
+++ gsl-1.1.1/interpolation/cspline.c	Mon Apr  1 14:52:12 2002
@@ -168,13 +168,25 @@
     return GSL_SUCCESS;
   } else {
     
-    state->offdiag[max_index] =  xa[1]-xa[0];
-    
-    for (i = 0; i < sys_size; i++) {
-      const double h_i   = xa[i + 1] - xa[i];
-      const double h_ip1 = xa[(i + 2) % num_points] - xa[i + 1];
+    for (i = 0; i < sys_size-1; i++) {
+      const double h_i       = xa[i + 1] - xa[i];
+      const double h_ip1     = xa[i + 2] - xa[i + 1];
+      const double ydiff_i   = ya[i + 1] - ya[i];
+      const double ydiff_ip1 = ya[i + 2] - ya[i + 1];
+      state->offdiag[i] = h_ip1;
+      state->diag[i] = 2.0 * (h_ip1 + h_i);
+      state->g[i] = 3.0 * (ydiff_ip1 / h_ip1 - ydiff_i / h_i);
+    }
+    /* fixed derivative discontinuity in xa[1], but not in xa[0] --
+     * this one is due to some tridiag solver problem
+     * FIXME
+     */
+    {
+      i = sys_size - 1;
+      const double h_i       = xa[i + 1] - xa[i];
+      const double h_ip1     = xa[1] - xa[0];
       const double ydiff_i   = ya[i + 1] - ya[i];
-      const double ydiff_ip1 = ya[(i + 2) % num_points] - ya[i + 1];
+      const double ydiff_ip1 = ya[1] - ya[0];
       state->offdiag[i] = h_ip1;
       state->diag[i] = 2.0 * (h_ip1 + h_i);
       state->g[i] = 3.0 * (ydiff_ip1 / h_ip1 - ydiff_i / h_i);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]