Linuxpops  3.01.04
Spectral Anaysis Package for Single Dish Data
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
grace_fit.c
Go to the documentation of this file.
1 
2 /*
3  * Grace - Graphics for Exploratory Data Analysis
4  *
5  * Home page: http://plasma-gate.weizmann.ac.il/Grace/
6  *
7  * Copyright (c) 1991-95 Paul J Turner, Portland, OR
8  * Copyright (c) 1996-98 GRACE Development Team
9  *
10  * Maintained by Evgeny Stambulchik <fnevgeny@plasma-gate.weizmann.ac.il>
11  *
12  *
13  * All Rights Reserved
14  *
15  * This program is free software; you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation; either version 2 of the License, or
18  * (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28  */
29 
30 /*
31  *
32  * curve fitting, and other numerical routines used in compose.
33  *
34  * Contents:
35  *
36  * void stasum() - compute mean and variance
37  * double leasev() - evaluate least squares polynomial
38  * int fitcurve() - compute coefficients for a polynomial fit of degree >1
39  * void runavg() - compute a running average
40  * void runstddev() - compute a running standard deviation
41  * void runmedian() - compute a running median
42  * void runminmax() - compute a running minimum or maximum
43  * void filterser() - apply a digital filter
44  * void linearconv() - convolve one set with another
45  * int crosscorr() - cross/auto correlation
46  * int linear_regression() - linear regression
47  * void spline() - compute a spline fit
48  * double seval() - evaluate the spline computed in spline()
49  */
50 
51 #include <stdlib.h>
52 #include <stdio.h>
53 #include <strings.h>
54 #include <string.h>
55 #include <math.h>
56 
57 #include <gsl/gsl_math.h>
58 #include <gsl/gsl_fit.h>
59 #include <gsl/gsl_vector.h>
60 #include <gsl/gsl_matrix.h>
61 #include <gsl/gsl_blas.h>
62 #include <gsl/gsl_multifit_nlinear.h>
63 #include <gsl/gsl_rng.h>
64 #include <gsl/gsl_randist.h>
65 
66 #include "../calc/config.h"
67 #include "defines.h"
68 #include "utils.h"
69 
70 //#include "channels.h"
71 
72 int dofitcurve(int cnt, double *xd, double *yd, int nd, double *c);
73 int linear_regression(int n, double *x, double *y, double *coeff);
74 
75 /*
76  * free and check for NULL pointer
77  */
78 void xfree(void *ptr)
79 {
80  if (ptr != NULL) {
81  free(ptr);
82  }
83 }
84 
85 
86 /*
87  * sort two arrays
88  */
89 void sort_xy(double *tmp1, double *tmp2, int up, int sorton, int stype)
90 {
91 
92  int d, i, j;
93  int lo = 0;
94  double t1, t2;
95 
96  if (sorton == 1) {
97  double *ttmp;
98 
99  ttmp = tmp1;
100  tmp1 = tmp2;
101  tmp2 = ttmp;
102  }
103  up--;
104 
105  for (d = up - lo + 1; d > 1;) {
106  if (d < 5)
107  d = 1;
108  else
109  d = (5 * d - 1) / 11;
110  for (i = up - d; i >= lo; i--) {
111  t1 = tmp1[i];
112  t2 = tmp2[i];
113  if (!stype) {
114  for (j = i + d; j <= up && (t1 > tmp1[j]); j += d) {
115  tmp1[j - d] = tmp1[j];
116  tmp2[j - d] = tmp2[j];
117  }
118  tmp1[j - d] = t1;
119  tmp2[j - d] = t2;
120  } else {
121  for (j = i + d; j <= up && (t1 < tmp1[j]); j += d) {
122  tmp1[j - d] = tmp1[j];
123  tmp2[j - d] = tmp2[j];
124  }
125  tmp1[j - d] = t1;
126  tmp2[j - d] = t2;
127  }
128  }
129  }
130 }
131 
132 
133 /*
134  compute mean and standard dev
135 */
136 void stasum(double *x, int n, double *xbar, double *sd)
137 {
138  int i;
139 
140  *xbar = 0;
141  *sd = 0;
142 
143  if (x == NULL) {
144  return;
145  }
146 
147  if (n < 1) {
148  return;
149  }
150 
151  for (i = 0; i < n; i++) {
152  *xbar = (*xbar) + x[i];
153  }
154  *xbar = (*xbar)/n;
155 
156  for (i = 0; i < n; i++) {
157  *sd = (*sd) + (x[i] - *xbar) * (x[i] - *xbar);
158  }
159  *sd = sqrt(*sd/n);
160 }
161 
162 
163 /*
164  evaluate least squares polynomial
165 */
166 double leasev(double *c, int degree, double x)
167 {
168  double temp;
169  int i;
170 
171  /*
172  * Commented out - refer to "Numerical Methods in C" for the
173  * reason, section 5.2! The revolution has begun.
174  temp = 0.0;
175  for (i = 0; i <= degree; i++) {
176  if ((i == 0) && (x == 0.0)) {
177  temp = temp + c[i];
178  } else {
179  temp = temp + c[i] * pow(x, (double) (i));
180  }
181  } */
182  temp = c[degree];
183  for( i=degree-1; i>=0; i-- )
184  temp = c[i] + temp*x;
185 
186  return (temp);
187 }
188 
189 
190 /* polynomial curve fitting */
191 int fitcurve(double *x, double *y, int n, int ideg, double *coeff)
192 /*
193  * x - x values
194  * y - y values
195  * n - number of points
196  * ideg - degree of fit
197  * coeff - coefficients of fit
198  */
199 {
200  int i, ifail;
201 
202  ifail = 1;
203 
204  if(ideg > 1)
205  {
206  dofitcurve(n, x, y, ideg, coeff);
207  }
208  else
209  {
210  ifail = linear_regression(n, x, y, coeff);
211 
212  if(ifail == 1)
213  {
214  fprintf(stderr, "Linear_regression entered with N < 2\n");
215  return ifail;
216  }
217  else
218  if(ifail == 2)
219  {
220  fprintf(stderr, "Linear_regression - all values of x or y are the same\n");
221  return ifail;
222  }
223  }
224  /* check coefficients */
225  for(i=0;i<=ideg;i++)
226  {
227  if(!gsl_finite(coeff[i]))
228  {
229  fprintf(stderr, "Linear_regression - all values of x or y are the same\n");
230  ifail = 3;
231  return ifail;
232  }
233  }
234 
235  ifail = 0;
236 
237  return(ifail);
238 }
239 
240 
241 /* compute a running average */
242 void runavg(double *x, double *y, double *ax, double *ay, int n, int ilen)
243 {
244  int i;
245  double sumy = 0.0;
246  double sumx = 0.0;
247 
248  for (i = 0; i < ilen; i++) {
249  sumx = sumx + x[i];
250  sumy = sumy + y[i];
251  }
252  ax[0] = sumx / ilen;
253  ay[0] = sumy / ilen;
254  for (i = 1; i < (n - ilen + 1); i++) {
255  sumx = x[i + ilen - 1] - x[i - 1] + sumx;
256  ax[i] = sumx / ilen;
257  sumy = y[i + ilen - 1] - y[i - 1] + sumy;
258  ay[i] = sumy / ilen;
259  }
260 }
261 
262 /*
263  compute a running standard deviation
264 */
265 void runstddev(double *x, double *y, double *ax, double *ay, int n, int ilen)
266 {
267  int i;
268  double ybar, ysd;
269  double sumx = 0.0;
270 
271  for (i = 0; i < ilen; i++) {
272  sumx = sumx + x[i];
273  }
274  ax[0] = sumx / ilen;
275  stasum(y, ilen, &ybar, &ysd);
276  ay[0] = ysd;
277  for (i = 1; i < (n - ilen + 1); i++) {
278  stasum(y + i, ilen, &ybar, &ysd);
279  sumx = x[i + ilen - 1] - x[i - 1] + sumx;
280  ax[i] = sumx / ilen;
281  ay[i] = ysd;
282  }
283 }
284 
285 /*
286  compute a running median
287 */
288 void runmedian(double *x, double *y, double *ax, double *ay, int n, int ilen)
289 {
290  int i, j, nlen = n - ilen + 1;
291  double *tmpx, *tmpy;
292 
293  tmpx = (double *) calloc(ilen, sizeof(double));
294  if (tmpx == NULL) {
295  fprintf(stderr, "Can't calloc tmpx in runmedian\n");
296  return;
297  }
298  tmpy = (double *) calloc(ilen, sizeof(double));
299  if (tmpy == NULL) {
300  fprintf(stderr, "Can't calloc tmpy in runmedian\n");
301  cxfree(tmpx);
302  return;
303  }
304  for (i = 0; i < nlen; i++) {
305  for (j = 0; j < ilen; j++) {
306  tmpx[j] = x[j + i];
307  tmpy[j] = y[j + i];
308  }
309  sort_xy(tmpx, tmpy, ilen, 1, 0);
310 
311  if (ilen % 2) {
312  ax[i] = x[i + (ilen / 2)];
313  ay[i] = tmpy[ilen / 2];
314  } else {
315  ax[i] = (x[i + ilen / 2] + x[i + (ilen - 1) / 2]) * 0.5;
316  ay[i] = (tmpy[ilen / 2] + tmpy[(ilen - 1) / 2]) * 0.5;
317  }
318  }
319  cxfree(tmpx);
320  cxfree(tmpy);
321 }
322 
323 /*
324  compute a running minimum or maximum
325 */
326 void runminmax(double *x, double *y, double *ax, double *ay, int n, int ilen, int type)
327 {
328  int i, j;
329  double min, max;
330  double sumx = 0.0;
331 
332  min = max = y[0];
333  for (i = 0; i < ilen; i++) {
334  sumx = sumx + x[i];
335  if (min > y[i])
336  min = y[i];
337  if (max < y[i])
338  max = y[i];
339  }
340  ax[0] = sumx / ilen;
341  if (type == 0) {
342  ay[0] = min;
343  } else if (type == 1) {
344  ay[0] = max;
345  } else {
346  fprintf(stderr, "Unknown type in runminmax, setting type = min\n");
347  type = 0;
348  }
349  for (i = 1; i < (n - ilen + 1); i++) {
350  sumx = x[i + ilen - 1] - x[i - 1] + sumx;
351  ax[i] = sumx / ilen;
352  min = y[i];
353  max = y[i];
354  for (j = 0; j < ilen; j++) {
355  if (min > y[i + j])
356  min = y[i + j];
357  if (max < y[i + j])
358  max = y[i + j];
359  }
360  if (type == 0) {
361  ay[i] = min;
362  } else if (type == 1) {
363  ay[i] = max;
364  }
365  }
366 }
367 
368 /*
369  Apply a digital filter of length len to a set in x, y,
370  of length n with the results going to resx, resy.
371  the length of the result is set by the caller
372 */
373 void filterser(int n, double *x, double *y, double *resx, double *resy, double *h, int len)
374 {
375  int i, j, outlen, eo, ld2;
376  double sum;
377 
378  outlen = n - len + 1;
379  eo = len % 2;
380  ld2 = len / 2;
381  for (i = 0; i < outlen; i++) {
382  sum = 0.0;
383  for (j = 0; j < len; j++) {
384  sum = sum + h[j] * y[j + i];
385  }
386  resy[i] = sum;
387  if (eo)
388  resx[i] = x[i + ld2];
389  else
390  resx[i] = (x[i + ld2] + x[i + ld2 - 1]) / 2.0;
391  }
392 }
393 
394 /*
395  linear convolution of set x (length n) with h (length m) and
396  result to y. the length of y is set by the caller
397 */
398 void linearconv(double *x, double *h, double *y, int n, int m)
399 {
400  int i, j, itmp;
401 
402  for (i = 0; i < n + m - 1; i++) {
403  for (j = 0; j < m; j++) {
404  itmp = i - j;
405  if ((itmp >= 0) && (itmp < n)) {
406  y[i] = y[i] + h[j] * x[itmp];
407  }
408  }
409  }
410 }
411 
412 /*
413  * cross correlation
414  */
415 int crosscorr(double *x, double *y, int n, int maxlag, double *xcov, double *xcor)
416 {
417  double xbar, xsd;
418  double ybar, ysd;
419  int i, j;
420 
421  if (maxlag + 2 > n)
422  return 1;
423  for (i = 0; i <= maxlag; i++) {
424  stasum(&x[i], n - i, &xbar, &xsd);
425  if (xsd == 0.0)
426  return 2;
427  stasum(y, n - i, &ybar, &ysd);
428  if (ysd == 0.0)
429  return 3;
430  xcov[i] = 0.0;
431  for (j = 0; j < n - i; j++) {
432  xcov[i] += (y[j] - ybar) * (x[j + i] - xbar);
433  }
434  xcov[i] /= n - i;
435  xcor[i] = xcov[i] / (xsd * ysd);
436  }
437  return 0;
438 }
439 
440 /* References,
441 
442  _Aplied Linear Regression_, Weisberg
443  _Elements of Statistical Computing_, Thisted
444 
445  Fits y = coef*x + intercept + e
446 
447  uses a 2 pass method for means and variances
448 */
449 int linear_regression(int n, double *x, double *y, double *coeff)
450 {
451  double xbar, ybar; /* sample means */
452  double sdx, sdy; /* sample standard deviations */
453  double sxy, rxy; /* sample covariance and sample correlation */
454  double SXX, SYY, SXY; /* sums of squares */
455  double RSS; /* residual sum of squares */
456  double rms; /* residual mean square */
457 // double sereg; /* standard error of regression */
458  double seslope, seintercept;
459  double slope, intercept; /* */
460  double SSreg, F /*, R2*/;
461  int i;
462  extern int debug;
463 
464  if(n < 2)
465  {
466  return(1);
467  }
468 
469  xbar = ybar = 0.0;
470  SXX = SYY = SXY = 0.0;
471 
472  for(i=0;i<n;i++)
473  {
474  xbar = xbar + x[i];
475  ybar = ybar + y[i];
476  }
477 
478  xbar = xbar / n;
479  ybar = ybar / n;
480 
481  for(i=0;i<n;i++)
482  {
483  SXX = SXX + (x[i] - xbar) * (x[i] - xbar);
484  SYY = SYY + (y[i] - ybar) * (y[i] - ybar);
485  SXY = SXY + (x[i] - xbar) * (y[i] - ybar);
486  }
487 
488  sdx = sqrt(SXX / (n - 1));
489  sdy = sqrt(SYY / (n - 1));
490 
491  if(sdx == 0.0)
492  {
493  return(2);
494  }
495 
496  if(sdy == 0.0)
497  {
498  return(2);
499  }
500 
501  sxy = SXY / (n - 1);
502  rxy = sxy / (sdx * sdy);
503  slope = SXY / SXX;
504  intercept = ybar - slope * xbar;
505  RSS = SYY - slope * SXY;
506 
507  if(debug)
508  {
509  printf("Number of observations\t\t = %d\n", n);
510  printf("Mean of independent variable\t = %12.7f\n", xbar);
511  printf("Mean of dependent variable\t\t = %12.7f\n", ybar);
512  printf("Standard dev. of ind. variable\t = %12.7f\n", sdx);
513  printf("Standard dev. of dep. variable\t = %12.7f\n", sdy);
514  printf("Correlation coefficient\t\t = %12.7f\n", rxy);
515  printf("Regression coefficient (SLOPE)\t = %12.7f\n", slope);
516  }
517 
518  if(n == 2)
519  {
520  coeff[1] = (y[1] - y[0])/(x[1] - x[0]);
521  coeff[0] = y[0] - coeff[1]*x[0];
522 
523  if(debug)
524  {
525  printf("Regression constant (INTERCEPT)\t = %12.7f\n", intercept);
526  }
527 
528  return(0);
529  }
530 
531  rms = RSS / (n - 2);
532 // sereg = sqrt(rms);
533  seintercept = sqrt(rms * (1.0 / n + xbar * xbar / SXX));
534  seslope = sqrt(rms / SXX);
535  SSreg = SYY - RSS;
536  F = SSreg / rms;
537 // R2 = SSreg / SYY;
538 
539  if(debug)
540  {
541  printf("Standard error of coefficient\t = %12.7f\n", seslope);
542  printf("t - value for coefficient\t\t = %12.7f\n", slope / seslope);
543  printf("Regression constant (INTERCEPT)\t = %12.7f\n", intercept);
544  printf("Standard error of constant\t\t = %12.7f\n", seintercept);
545  printf("t - value for constant\t\t = %12.7f\n", intercept / seintercept);
546  printf("Analysis of variance\n");
547 
548  printf("Source\t d.f\t Sum of squares\t Mean Square\t F\n");
549  printf("Regression\t 1\t%12.7f\t%12.7f\t%12.7f\n", SSreg, SSreg, F);
550  printf("Residual\t%5d\t%12.7f\t%12.7f\n", n - 2, RSS, rms);
551  printf("Total\t%5d\t%12.7f\n", n - 1, SYY);
552  }
553 
554  for(i=0;i<n;i++)
555  {
556  coeff[0] = intercept;
557  coeff[1] = slope;
558  coeff[2] = rxy;
559  }
560 
561  return(0);
562 }
563 
564 /*
565  a literal translation of the spline routine in
566  Forsyth, Malcolm, and Moler
567 */
568 void spline(int n, double *x, double *y, double *b, double *c, double *d)
569 {
570 /*
571 c
572 c the coefficients b(i), c(i), and d(i), i=1,2,...,n are computed
573 c for a cubic interpolating spline
574 c
575 c s(x) = y(i) + b(i)*(x-x(i)) + c(i)*(x-x(i))**2 + d(i)*(x-x(i))**3
576 c
577 c for x(i) .le. x .le. x(i+1)
578 c
579 c input..
580 c
581 c n = the number of data points or knots (n.ge.2)
582 c x = the abscissas of the knots in strictly increasing order
583 c y = the ordinates of the knots
584 c
585 c output..
586 c
587 c b, c, d = arrays of spline coefficients as defined above.
588 c
589 c using p to denote differentiation,
590 c
591 c y(i) = s(x(i))
592 c b(i) = sp(x(i))
593 c c(i) = spp(x(i))/2
594 c d(i) = sppp(x(i))/6 (derivative from the right)
595 c
596 c the accompanying function subprogram seval can be used
597 c to evaluate the spline.
598 c
599 c
600 */
601 
602  int nm1, ib, i;
603  double t;
604 
605 /*
606 Gack!
607 */
608  x--;
609  y--;
610  b--;
611  c--;
612  d--;
613 
614 /*
615 Fortran 66
616 */
617  nm1 = n - 1;
618  if (n < 2)
619  return;
620  if (n < 3)
621  goto l50;
622 /*
623 c
624 c set up tridiagonal system
625 c
626 c b = diagonal, d = offdiagonal, c = right hand side.
627 c
628 */
629  d[1] = x[2] - x[1];
630  c[2] = (y[2] - y[1]) / d[1];
631  for (i = 2; i <= nm1; i++) {
632  d[i] = x[i + 1] - x[i];
633  b[i] = 2.0 * (d[i - 1] + d[i]);
634  c[i + 1] = (y[i + 1] - y[i]) / d[i];
635  c[i] = c[i + 1] - c[i];
636  }
637 /*
638 c
639 c end conditions. third derivatives at x(1) and x(n)
640 c obtained from divided differences
641 c
642 */
643  b[1] = -d[1];
644  b[n] = -d[n - 1];
645  c[1] = 0.0;
646  c[n] = 0.0;
647  if (n == 3)
648  goto l15;
649  c[1] = c[3] / (x[4] - x[2]) - c[2] / (x[3] - x[1]);
650  c[n] = c[n - 1] / (x[n] - x[n - 2]) - c[n - 2] / (x[n - 1] - x[n - 3]);
651  c[1] = c[1] * d[1] * d[1] / (x[4] - x[1]);
652  c[n] = -c[n] * d[n - 1] * d[n - 1] / (x[n] - x[n - 3]);
653 /*
654 c
655 c forward elimination
656 c
657 */
658 l15:;
659  for (i = 2; i <= n; i++) {
660  t = d[i - 1] / b[i - 1];
661  b[i] = b[i] - t * d[i - 1];
662  c[i] = c[i] - t * c[i - 1];
663  }
664 /*
665 c
666 c back substitution
667 c
668 */
669  c[n] = c[n] / b[n];
670  for (ib = 1; ib <= nm1; ib++) {
671  i = n - ib;
672  c[i] = (c[i] - d[i] * c[i + 1]) / b[i];
673  }
674 /*
675 c
676 c c(i) is now the sigma(i) of the text
677 c
678 c compute polynomial coefficients
679 c
680 */
681  b[n] = (y[n] - y[nm1]) / d[nm1] + d[nm1] * (c[nm1] + 2.0 * c[n]);
682  for (i = 1; i <= nm1; i++) {
683  b[i] = (y[i + 1] - y[i]) / d[i] - d[i] * (c[i + 1] + 2.0 * c[i]);
684  d[i] = (c[i + 1] - c[i]) / d[i];
685  c[i] = 3.0 * c[i];
686  }
687  c[n] = 3.0 * c[n];
688  d[n] = d[n - 1];
689  return;
690 
691 l50:;
692  b[1] = (y[2] - y[1]) / (x[2] - x[1]);
693  c[1] = 0.0;
694  d[1] = 0.0;
695  b[2] = b[1];
696  c[2] = 0.0;
697  d[2] = 0.0;
698  return;
699 }
700 
701 /***************************************************************************
702  * aspline - modified version of David Frey's spline.c *
703  * *
704  * aspline does an Akima spline interpolation. *
705  ***************************************************************************/
706 
707 void aspline(int n, double *x, double *y, double *b, double *c, double *d)
708 {
709  int i;
710 
711  double num, den;
712  double m_m1, m_m2, m_p1, m_p2;
713  double x_m1, x_m2, x_p1, x_p2;
714  double y_m1, y_m2, y_p1, y_p2;
715 
716 #define dx(i) (x[i+1]-x[i])
717 #define dy(i) (y[i+1]-y[i])
718 #define m(i) (dy(i)/dx(i))
719 
720  if (n > 0) /* we have data to process */
721  {
722 
723  /*
724  * calculate the coefficients of the spline
725  * (the Akima interpolation itself)
726  */
727 
728  /* b) interpolate the missing points: */
729 
730  x_m1 = x[0] + x[1] - x[2];
731  y_m1 = (x[0]-x_m1) * (m(1) - 2 * m(0)) + y[0];
732 
733  m_m1 = (y[0]-y_m1)/(x[0]-x_m1);
734 
735  x_m2 = 2 * x[0] - x[2];
736  y_m2 = (x_m1-x_m2) * (m(0) - 2 * m_m1) + y_m1;
737 
738  m_m2 = (y_m1-y_m2)/(x_m1-x_m2);
739 
740  x_p1 = x[n-1] + x[n-2] - x[n-3];
741  y_p1 = (2 * m(n-2) - m(n-3)) * (x_p1 - x[n-1]) + y[n-1];
742 
743  m_p1 = (y_p1-y[n-1])/(x_p1-x[n-1]);
744 
745  x_p2 = 2 * x[n-1] - x[n-3];
746  y_p2 = (2 * m_p1 - m(n-2)) * (x_p2 - x_p1) + y_p1;
747 
748  m_p2 = (y_p2-y_p1)/(x_p2-x_p1);
749 
750  /* i = 0 */
751  num=fabs(m(1) - m(0)) * m_m1 + fabs(m_m1 - m_m2) * m(0);
752  den=fabs(m(1) - m(0)) + fabs(m_m1 - m_m2);
753 
754  if (den != 0.0) b[0]=num / den;
755  else b[0]=0.0;
756 
757  /* i = 1 */
758  num=fabs(m(2) - m(1)) * m(0) + fabs(m(0) - m_m1) * m(1);
759  den=fabs(m(2) - m(1)) + fabs(m(0) - m_m1);
760 
761  if (den != 0.0) b[1]=num / den;
762  else b[1]=0.0;
763 
764  for (i=2; i < n-2; i++)
765  {
766 
767  num=fabs(m(i+1) - m(i)) * m(i-1) + fabs(m(i-1) - m(i-2)) * m(i);
768  den=fabs(m(i+1) - m(i)) + fabs(m(i-1) - m(i-2));
769 
770  if (den != 0.0) b[i]=num / den;
771  else b[i]=0.0;
772  }
773 
774  /* i = n - 2 */
775  num=fabs(m_p1 - m(n-2)) * m(n-3) + fabs(m(n-3) - m(n-4)) * m(n-2);
776  den=fabs(m_p1 - m(n-2)) + fabs(m(n-3) - m(n-4));
777 
778  if (den != 0.0) b[n-2]=num / den;
779  else b[n-2]=0.0;
780 
781  /* i = n - 1 */
782  num=fabs(m_p2 - m_p1) * m(n-2) + fabs(m(n-2) - m(n-3)) * m_p1;
783  den=fabs(m_p2 - m_p1) + fabs(m(n-2) - m(n-3));
784 
785  if (den != 0.0) b[n-1]=num / den;
786  else b[n-1]=0.0;
787 
788  for (i=0; i < n-1; i++)
789  {
790  double dxv = dx(i);
791  c[i]=(3 * m(i) - 2 * b[i] - b[i+1]) / dxv;
792  d[i]=(b[i] + b[i+1] - 2 * m(i)) / (dxv * dxv);
793  }
794  }
795 #undef dx
796 #undef dy
797 #undef m
798 }
799 
800 double seval(int n, double u, double *x, double *y, double *b, double *c, double *d)
801 {
802 /*
803 c
804 c this subroutine evaluates the cubic spline function
805 c
806 c seval = y(i) + b(i)*(u-x(i)) + c(i)*(u-x(i))**2 + d(i)*(u-x(i))**3
807 c
808 c where x(i) .lt. u .lt. x(i+1), using horner's rule
809 c
810 c if u .lt. x(1) then i = 1 is used.
811 c if u .ge. x(n) then i = n is used.
812 c
813 c input..
814 c
815 c n = the number of data points
816 c u = the abscissa at which the spline is to be evaluated
817 c x,y = the arrays of data abscissas and ordinates
818 c b,c,d = arrays of spline coefficients computed by spline
819 c
820 c if u is not in the same interval as the previous call, then a
821 c binary search is performed to determine the proper interval.
822 c
823 */
824  int j, k;
825  double dx;
826  int i;
827 
828 /*
829 c
830 c binary search
831 c
832 */
833  if (u < x[0]) {
834  i = 0;
835  } else if (u >= x[n - 1]) {
836  i = n - 1;
837  } else {
838  i = 0;
839  j = n;
840 l20: ;
841  k = (i + j) / 2;
842  if (u < x[k])
843  j = k;
844  if (u >= x[k])
845  i = k;
846  if (j > i + 1)
847  goto l20;
848  }
849 /*
850 c
851 c evaluate spline
852 c
853 */
854  dx = u - x[i];
855  return (y[i] + dx * (b[i] + dx * (c[i] + dx * d[i])));
856 }
857 
double seval(int n, double u, double *x, double *y, double *b, double *c, double *d)
Definition: grace_fit.c:847
void xfree(void *ptr)
Definition: grace_fit.c:122
#define cxfree(ptr)
Definition: utils.h:50
#define max(a, b)
Definition: cactus.h:115
#define min(a, b)
Definition: cactus.h:114
void runminmax(double *x, double *y, double *ax, double *ay, int n, int ilen, int type)
Definition: grace_fit.c:374
int crosscorr(double *x, double *y, int n, int maxlag, double *xcov, double *xcor)
Definition: grace_fit.c:463
int debug
Definition: mailparse.c:29
int dofitcurve(int cnt, double *xd, double *yd, int nd, double *c)
Definition: grace_dofit.c:976
void runmedian(double *x, double *y, double *ax, double *ay, int n, int ilen)
Definition: grace_fit.c:336
double sum
Definition: beam.h:5
int fitcurve(double *x, double *y, int n, int ideg, double *coeff)
Definition: grace_fit.c:239
void runstddev(double *x, double *y, double *ax, double *ay, int n, int ilen)
Definition: grace_fit.c:313
void runavg(double *x, double *y, double *ax, double *ay, int n, int ilen)
Definition: grace_fit.c:290
double leasev(double *c, int degree, double x)
Definition: grace_fit.c:210
int linear_regression(int n, double *x, double *y, double *coeff)
Definition: grace_fit.c:497
void linearconv(double *x, double *h, double *y, int n, int m)
Definition: grace_fit.c:446
void stasum(double *x, int n, double *xbar, double *sd)
Definition: grace_fit.c:180
#define m(i)
double rms
Definition: beam.h:5
void filterser(int n, double *x, double *y, double *resx, double *resy, double *h, int len)
Definition: grace_fit.c:421
#define dx(i)
void spline(int n, double *x, double *y, double *b, double *c, double *d)
Definition: grace_fit.c:615
struct SPECDATA sd
Definition: otf.c:43
void sort_xy(double *tmp1, double *tmp2, int up, int sorton, int stype)
Definition: grace_fit.c:133
void aspline(int n, double *x, double *y, double *b, double *c, double *d)
Definition: grace_fit.c:754