Linuxpops  3.01.04
Spectral Anaysis Package for Single Dish Data
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
grace_dofit.c
Go to the documentation of this file.
1 /*
2  * Grace - Graphics for Exploratory Data Analysis
3  *
4  * Home page: http://plasma-gate.weizmann.ac.il/Grace/
5  *
6  * Copyright (c) 1991-95 Paul J Turner, Portland, OR
7  * Copyright (c) 1996-98 GRACE Development Team
8  *
9  * Maintained by Evgeny Stambulchik <fnevgeny@plasma-gate.weizmann.ac.il>
10  *
11  *
12  * All Rights Reserved
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27  */
28 
29 #include "ds_extern.h"
30 #include "ds_proto.h"
31 
32 /* ALGORITHM AS274.1 APPL. STATIST. (1992) VOL 41, NO. 2
33 
34  Calling this routine updates d, rbar, thetab and sserr by the
35  inclusion of xrow, yelem with the specified weight. This version has
36  been modified to make it slightly faster when the early elements of
37  XROW are not zeroes. *** WARNING *** The elements of XROW are
38  over-written. */
39 int gf_includ(np, nrbar, w, xrow, y, d, rbar, thetab, sserr)
40 int np, nrbar;
41 double w, *xrow, y, *d, *rbar, *thetab, *sserr;
42 {
43  int ier=0, i, k, nextr;
44  double cbar, sbar, di, xi, xk, dpi, wxi;
45 
46 
47  --thetab;
48  --rbar;
49  --d;
50  --xrow;
51 
52  /* the function includ() is called for each obs, and is where all
53  the time is spent. To make it faster, we skip the checks about
54  whether nrbar is big enough for np. If you'd like to have the
55  checks in anyway, then compile with -DSTRINGENT */
56 #ifdef STRINGENT /* Some checks. */
57  if(np < 1)
58  {
59  ier = 1;
60  }
61 
62  if(nrbar < np * (np - 1) / 2)
63  {
64  ier += 2;
65  }
66 
67  if(ier)
68  {
69  return(ier);
70  }
71 
72 #endif /* STRINGENT */
73 
74  nextr = 1;
75 
76 /* Skip unnecessary transformations. Test on exact zeroes must be used or stability can be destroyed. */
77 
78  for(i=1;i<=np;++i)
79  {
80  if(w == 0)
81  {
82  return(ier);
83  }
84 
85  xi = xrow[i];
86 
87  if(xi == 0)
88  {
89  nextr += np - i;
90  }
91  else
92  {
93  di = d[i];
94  wxi = w * xi;
95  dpi = di + wxi * xi;
96  cbar = di / dpi;
97  sbar = wxi / dpi;
98  w = cbar * w;
99  d[i] = dpi;
100 
101  if(i != np)
102  {
103  for(k=i+1;k<=np;++k)
104  {
105  xk = xrow[k];
106  xrow[k] = xk - xi * rbar[nextr];
107  rbar[nextr] = cbar * rbar[nextr] + sbar * xk;
108  ++nextr;
109  }
110  }
111 
112  xk = y;
113  y = xk - xi * thetab[i];
114  thetab[i] = cbar * thetab[i] + sbar * xk;
115  }
116  }
117 
118 /* Y * SQRT(W) is now equal to the Brown, Durbin & Evans recursive residual. */
119  *sserr += w * y * y;
120 
121  return(ier);
122 }
123 
124 
125 
126 /* ALGORITHM AS274.2 APPL. STATIST. (1992) VOL.41, NO. 2
127  Sets arrays to zero prior to calling AS75.1 */
128 int gf_clear(np, nrbar, d, rbar, thetab, sserr)
129 int np, nrbar;
130 double *d, *rbar, *thetab, *sserr;
131 {
132  int ier=0;
133 
134  if(np < 1)
135  {
136  ier = 1;
137  }
138 
139  if(nrbar < (np * (np - 1) / 2))
140  {
141  ier += 2;
142  }
143 
144  if(ier)
145  {
146  return(ier);
147  }
148 
149  memset(d, 0, np * sizeof(double));
150  memset(thetab, 0, np * sizeof(double));
151  memset(rbar, 0, nrbar * sizeof(double));
152 
153  *sserr = 0;
154 
155  return(0);
156 }
157 
158 
159 int gf_regcf(int np, int nrbar, double *d, double *rbar,
160  double *thetab, double *tol, double *beta,
161  int nreq)
162 {
163  int ier=0, i, j, nextr;
164 
165 /* ALGORITHM AS274.3 APPL. STATIST. (1992) VOL 41, NO.2
166  Modified version of AS75.4 to calculate regression coefficients
167  for the first NREQ variables, given an orthogonal reduction from
168  AS75.1. */
169 
170  --beta; --tol; --thetab; --rbar; --d;
171 
172  /* Some checks. */
173  if (np < 1) ier = 1;
174  if (nrbar < np * (np - 1) / 2) ier += 2;
175  if (nreq < 1 || nreq > np) ier += 4;
176  if (ier) return ier;
177 
178  for (i = nreq; i >= 1; --i)
179  if (sqrt(d[i]) < tol[i]) {
180  beta[i] = d[i] = 0;
181  } else {
182  beta[i] = thetab[i];
183  nextr = (i - 1) * (np + np - i) / 2 + 1;
184  for (j=i+1; j<=nreq; ++j) beta[i] -= rbar[nextr++] * beta[j];
185  }
186 
187  return ier;
188 } /* regcf */
189 
190 
191 int gf_tolset(int np, int nrbar, double *d, double *rbar, double *tol)
192 /* ALGORITHM AS274.4 APPL. STATIST. (1992) VOL 41, NO.2
193  Sets up array TOL for testing for zeroes in an orthogonal
194  reduction formed using AS75.1.
195  EPS is a machine-dependent constant. For compilers which use
196  the IEEE format for floating-point numbers, recommended values
197  are 1.E-06 for single precision and 1.E-15 for double precision. */
198 {
199  const double eps = 1e-15;
200  double d__1, sum, *work;
201  int ier=0, col, pos, row;
202 
203  --tol; --rbar; --d;
204 
205  /* Some checks. */
206  if (np < 1) ier = 1;
207  if (nrbar < np * (np - 1) / 2) ier += 2;
208  if (ier) return ier;
209 
210 /* Set TOL(I) = sum of absolute values in column I of RBAR after
211  scaling each element by the square root of its row multiplier. */
212 
213  work = -1 + (double *) malloc(np*sizeof(double));
214  for (col = 1; col <= np; ++col) work[col] = sqrt(d[col]);
215  for (col = 1; col <= np; ++col) {
216  pos = col - 1;
217  sum = work[col];
218  for (row = 1; row <= col-1; ++row) {
219  sum += (d__1 = rbar[pos], fabs(d__1)) * work[row];
220  pos += np - row - 1;
221  }
222  tol[col] = eps * sum;
223  }
224  free(work+1);
225  return 0;
226 } /* tolset */
227 
228 
229 int gf_sing(int np, int nrbar, double *d,
230  double *rbar, double *thetab, double *sserr,
231  double *tol, int *lindep)
232 /* ALGORITHM AS274.5 APPL. STATIST. (1992) VOL 41, NO. 2
233  Checks for singularities, reports, and adjusts orthogonal
234  reductions produced by AS75.1. */
235 {
236  double d__1, temp, *work;
237  int ier=0, np2, col, pos, row, pos2;
238 
239  --lindep; --tol; --thetab; --rbar; --d;
240 
241  if (np <= 0) ier = 1;
242  if (nrbar < np * (np - 1) / 2) ier += 2;
243  if (ier) return ier;
244  work = -1 + (double *) malloc(np*sizeof(double));
245 
246 /* Set elements within RBAR to zero if they are less than TOL(COL) in
247  absolute value after being scaled by the square root of their row
248  multiplier. */
249  for (col = 1; col <= np; ++col) work[col] = sqrt(d[col]);
250  for (col = 1; col <= np; ++col) {
251  temp = tol[col];
252  pos = col - 1;
253  for (row = 1; row < col; ++row) {
254  if ((d__1 = rbar[pos], fabs(d__1)) * work[row] < temp)
255  rbar[pos] = 0;
256  pos += np - row - 1;
257  }
258 
259 /* If diagonal element is near zero, set it to zero, set appropriate
260  element of LINDEP, and use INCLUD to augment the projections in
261  the lower rows of the orthogonalization. */
262 
263  lindep[col] = 0;
264  if (work[col] < temp) {
265  lindep[col] = 1;
266  --ier;
267  if (col < np) {
268  np2 = np - col;
269  pos2 = pos + np2 + 1;
270  ier = gf_includ(np2, np2*(np2-1)/2, d[col], rbar+pos+1,
271  thetab[col], d+col+1, rbar+pos2,
272  thetab+col+1, sserr);
273  } else {
274  d__1 = thetab[col]; /* for squaring */
275  *sserr += d[col] * (d__1 * d__1);
276  }
277  d[col] = work[col] = thetab[col] = 0;
278  }
279  }
280  free(work+1);
281  return ier;
282 } /* sing */
283 
284 
285 int gf_ss(int np, double *d, double *thetab, double *sserr, double *rss)
286 /* ALGORITHM AS274.6 APPL. STATIST. (1992) VOL 41, NO. 2
287  Calculates partial residual sums of squares from an orthogonal
288  reduction from AS75.1. */
289 {
290  double sum;
291  int i;
292 
293  --rss; --thetab; --d;
294 
295  if (np < 1) return 1;
296  sum = rss[np] = *sserr;
297  for (i = np; i >= 2; --i) {
298  sum += d[i] * thetab[i] * thetab[i];
299  rss[i - 1] = sum;
300  }
301  return 0;
302 } /* ss */
303 
304 
305 int gf_cov(int np, int nrbar, double *d,
306  double *rbar, int nreq, double *rinv, double *var,
307  double *covmat, int dimcov, double *sterr)
308 /* ALGORITHM AS274.7 APPL. STATIST. (1992) VOL 41, NO.2
309  Calculate covariance matrix for regression coefficients for the
310  first NREQ variables, from an orthogonal reduction produced from
311  AS75.1. */
312 {
313  int ier=0, k, start, col, pos, row, pos1, pos2;
314  double sum;
315 
316  --sterr; --covmat; --rinv; --rbar; --d;
317 
318  if (np < 1) ier = 1;
319  if (nrbar < np * (np - 1) / 2) ier += 2;
320  if (dimcov < nreq * (nreq + 1) / 2) ier += 4;
321 
322  for (row = 1; row <= nreq; ++row) if (d[row] == 0) ier = -row;
323  if (ier) return ier;
324 
325  gf_inv(np, nrbar, rbar+1, nreq, rinv+1);
326  start = pos = 1;
327  for (row = 1; row <= nreq; ++row) {
328  pos2 = start;
329  for (col = row; col <= nreq; ++col) {
330  pos1 = start + col - row;
331  sum = (row == col ? 1.0 : rinv[pos1-1])/d[col];
332  for (k = col + 1; k <= nreq; ++k)
333  sum += rinv[pos1++] * rinv[pos2++] / d[k];
334  covmat[pos] = sum * *var;
335  if (row == col) sterr[row] = sqrt(covmat[pos]);
336  ++pos;
337  }
338  start += nreq - row;
339  }
340  return 0;
341 } /* cov */
342 
343 
344 void gf_inv(int np, int nrbar, double *rbar, int nreq, double *rinv)
345 /* ALGORITHM AS274.8 APPL. STATIST. (1992) VOL 41, NO. 2
346  Invert first NREQ rows and columns of Cholesky factorization
347  produced by AS75.1. */
348 {
349  int pos, row;
350 
351  --rinv; --rbar;
352 
353  /* Invert RBAR ignoring row multipliers, from the bottom up. */
354  pos = nreq * (nreq - 1) / 2;
355  for (row = nreq - 1; row >= 1; --row) {
356  int col, start = (row - 1) * (np + np - row) / 2 + 1;
357  for (col = nreq; col >= row+1; --col) {
358  double sum=0;
359  int pos1=start, pos2=pos, k;
360  for (k = row + 1; k <= col-1; ++k) {
361  pos2 += nreq - k;
362  sum -= rbar[pos1++] * rinv[pos2];
363  }
364  rinv[pos] = sum - rbar[pos1];
365  --pos;
366  }
367  }
368 } /* inv */
369 
370 
371 int gf_pcorr(int np, int nrbar, double *d,
372  double *rbar, double *thetab, double *sserr, int in,
373  double *cormat, int dimc, double *ycorr)
374 /* ALGORITHM AS274.9 APPL. STATIST. (1992) VOL 41, NO. 2
375  Calculate partial correlations after the first IN variables
376  have been forced into the regression. */
377 {
378  int ier=0, i, start, in1;
379  double *work;
380 
381  --cormat; --thetab; --rbar; --d;
382 
383  if (np < 1) ier = 1;
384  if (nrbar < np * (np - 1) / 2) ier += 2;
385  if (in < 0 || in > np - 1) ier += 4;
386  if (dimc < (np - in) * (np - in - 1) / 2) ier += 8;
387  if (ier) return ier;
388 
389  start = in * (np + np - in - 1) / 2 + 1;
390  in1 = in + 1;
391  work = (double *) malloc(np*sizeof(double));
392  gf_cor(np-in, d+in1, rbar+start, thetab+in1, sserr, work, cormat+1, ycorr);
393 
394  /* Check for zeroes. */
395  for (i=0; i<(np-in); ++i) if (work[i] <= 0) ier = -1-i;
396  free(work);
397  return ier;
398 } /* pcorr */
399 
400 
401 void gf_cor(int np, double *d, double *rbar,
402  double *thetab, double *sserr, double *work,
403  double *cormat, double *ycorr)
404 /* ALGORITHM AS274.10 APPL. STATIST. (1992) VOL 41, NO.2
405  Calculate correlations from an orthogonal reduction. This
406  routine will usually be called from PCORR, which will have
407  removed the appropriate number of rows at the start. */
408 {
409  int i__1, i__2, diff, pos, row, col1, col2, pos1, pos2;
410  double sumy, sum;
411 
412  --ycorr; --cormat; --work; --thetab; --rbar; --d;
413 
414 /* process by columns, including the projections of the dependent
415  variable (THETAB). */
416  sumy = *sserr;
417  i__1 = np;
418  for (row = 1; row <= i__1; ++row)
419  sumy += d[row] * thetab[row] * thetab[row];
420  sumy = sqrt(sumy);
421 
422  pos = np * (np - 1) / 2;
423  for (col1 = np; col1 >= 1; --col1) { /* find length of column COL1. */
424  sum = d[col1];
425  i__1 = pos1 = col1 - 1;
426  for (row = 1; row <= i__1; ++row) {
427  sum += d[row] * rbar[pos1] * rbar[pos1];
428  pos1 += np - row - 1;
429  }
430  work[col1] = sqrt(sum);
431 
432 /* If SUM = 0, set all correlations with this variable to zero. */
433  if (sum == 0) {
434  ycorr[col1] = 0;
435  i__1 = col1 + 1;
436  for (col2 = np; col2 >= i__1; --col2) {
437  cormat[pos] = 0; --pos;
438  }
439  goto L70;
440  }
441 
442 /* Form cross-products, then divide by product of column lengths. */
443  sum = d[col1] * thetab[col1];
444  i__1 = pos1 = col1 - 1;
445  for (row = 1; row <= i__1; ++row) {
446  sum += d[row] * rbar[pos1] * thetab[row];
447  pos1 += np - row - 1;
448  }
449  ycorr[col1] = sum / (sumy * work[col1]);
450 
451  i__1 = col1 + 1;
452  for (col2 = np; col2 >= i__1; --col2) {
453  if (work[col2] > 0) {
454  pos1 = col1 - 1;
455  pos2 = col2 - 1;
456  diff = col2 - col1;
457  i__2 = col1 - 1;
458  for (sum=0, row = 1; row <= i__2; ++row) {
459  sum += d[row] * rbar[pos1] * rbar[pos2];
460  pos1 += np - row - 1;
461  pos2 = pos1 + diff;
462  }
463  sum += d[col1] * rbar[pos2];
464  cormat[pos] = sum / (work[col1] * work[col2]);
465  } else cormat[pos] = 0;
466  --pos;
467  }
468 L70:
469  ;
470  }
471 } /* cor */
472 
473 
474 
475 
476 /* ALGORITHM AS274.11 APPL. STATIST. (1992) VOL 41, NO. 2
477  * Move variable from position FROM to position TO in an
478  * orthogonal reduction produced by AS75.1.
479  */
480 int gf_vmove(np, nrbar, vorder, d, rbar, thetab, rss, from, to, tol)
481 int np, nrbar, *vorder;
482 double *d, *rbar, *thetab, *rss;
483 int from, to;
484 double *tol;
485 {
486  int ier=0, last, m;
487  double d__1, cbar, sbar, d1new, d2new, x, y, d1, d2;
488  int first, m1, m2, mp1, inc, col, pos, row;
489 
490  --tol;
491  --rss;
492  --thetab;
493  --rbar;
494  --d;
495  --vorder;
496 
497  if(np <= 0)
498  {
499  ier = 1;
500  }
501 
502  if(nrbar < np * (np - 1) / 2)
503  {
504  ier += 2;
505  }
506 
507  if(from < 1 || from > np)
508  {
509  ier += 4;
510  }
511 
512  if(to < 1 || to > np)
513  {
514  ier += 8;
515  }
516 
517  if(ier)
518  {
519  return ier;
520  }
521 
522  if(from == to)
523  {
524  return ier;
525  }
526 
527  if(from < to)
528  {
529  first = from;
530  last = to - 1;
531  inc = 1;
532  }
533  else
534  {
535  first = from - 1;
536  last = to;
537  inc = -1;
538  }
539 
540 /* Find addresses of first elements of RBAR in rows M and (M+1). */
541  for (m = first; inc < 0 ? m >= last : m <= last; m += inc)
542  {
543  m1 = (m - 1) * (np + np - m) / 2 + 1;
544  m2 = m1 + np - m;
545  mp1 = m + 1;
546  d1 = d[m];
547  d2 = d[mp1];
548 
549  /* Special cases. */
550  if(d1 == 0 && d2 == 0)
551  {
552  goto L40;
553  }
554 
555  x = rbar[m1];
556  if(fabs(x) * sqrt(d1) < tol[mp1])
557  {
558  x = 0;
559  }
560 
561  if(d1 == 0 || x == 0)
562  {
563  d[m] = d2;
564  d[mp1] = d1;
565  rbar[m1] = 0;
566 
567  for (col = m + 2; col <= np; ++col)
568  {
569  x = rbar[++m1];
570  rbar[m1] = rbar[m2];
571  rbar[m2++] = x;
572  }
573 
574  x = thetab[m];
575  thetab[m] = thetab[mp1];
576  thetab[mp1] = x;
577 
578  goto L40;
579  }
580  else
581  if(d2 == 0)
582  {
583  d__1 = x;
584  d[m] = d1 * d__1 * d__1;
585  rbar[m1] = 1.0/x;
586 
587  for(col = m + 2; col <= np; ++col)
588  {
589  rbar[++m1] /= x;
590  thetab[m] /= x;
591  }
592 
593  goto L40;
594  }
595 
596 /* Planar rotation in regular case. */
597  d__1 = x;
598  d1new = d2 + d1 * (d__1 * d__1);
599  cbar = d2 / d1new;
600  sbar = x * d1 / d1new;
601  d2new = d1 * cbar;
602  d[m] = d1new;
603  d[mp1] = d2new;
604  rbar[m1] = sbar;
605 
606  for(col = m + 2; col <= np; ++col)
607  {
608  y = rbar[++m1];
609  rbar[m1] = cbar * rbar[m2] + sbar * y;
610  rbar[m2] = y - x * rbar[m2];
611  ++m2;
612  }
613 
614  y = thetab[m];
615  thetab[m] = cbar * thetab[mp1] + sbar * y;
616  thetab[mp1] = y - x * thetab[mp1];
617 
618 /* Swap columns M and (M+1) down to row (M-1). */
619 L40:
620  if(m == 1)
621  {
622  goto L60;
623  }
624 
625  pos = m;
626 
627  for(row = 1; row < m; ++row)
628  {
629  x = rbar[pos];
630  rbar[pos] = rbar[pos - 1];
631  rbar[pos - 1] = x;
632  pos += np - row - 1;
633  }
634 
635 /* Adjust variable order (VORDER), the tolerances (TOL) and the vector
636  of residual sums of squares (RSS). */
637 L60:
638  m1 = vorder[m];
639  vorder[m] = vorder[mp1];
640  vorder[mp1] = m1;
641  x = tol[m];
642  tol[m] = tol[mp1];
643  tol[mp1] = x;
644  d__1 = thetab[mp1];
645  rss[m] = rss[mp1] + d[mp1] * (d__1 * d__1);
646  }
647 
648  return(0);
649 } /* gf_vmove */
650 
651 
652 /* ALGORITHM AS274.12 APPL. STATIST. (1992) VOL 41, NO.2 Re-order the
653  * variables in an orthogonal reduction produced by AS75.1 so that the N
654  * variables in LIST start at position POS1, though will not necessarily
655  * be in the same order as in LIST. Any variables in VORDER before
656  * position POS1 are not moved. Auxiliary routine called: VMOVE
657  */
658 int gf_reordr(np, nrbar, vorder, d, rbar, thetab, rss, tol, list, n, pos1)
659 int np, nrbar, *vorder;
660 double *d, *rbar, *thetab, *rss, *tol;
661 int *list, n, pos1;
662 {
663  int ier=0, next, i, j;
664 
665  --list;
666  --tol;
667  --rss;
668  --thetab;
669  --rbar;
670  --d;
671  --vorder;
672 
673  if(np < 1)
674  {
675  ier = 1;
676  }
677 
678  if(nrbar < np * (np - 1) / 2)
679  {
680  ier += 2;
681  }
682 
683  if(n < 1 || n >= np + 1 - pos1)
684  {
685  ier += 4;
686  }
687 
688  if(ier)
689  {
690  return(ier);
691  }
692 
693 /* Work through VORDER finding variables which are in LIST. */
694  i = next = pos1;
695  do
696  {
697  int l=vorder[i];
698 
699  for (j=1; j<=n; j++)
700  {
701  if (l==list[j])
702  {
703  if (i > next)
704  {
705  gf_vmove(np, nrbar, vorder+1, d+1, rbar+1, thetab+1, rss+1, i, next, tol+1);
706  }
707 
708  if(++next >= n + pos1)
709  {
710  return 0;
711  }
712 
713  break;
714  }
715  }
716  }while(++i <= np);
717 
718  return(8);
719 } /* gf_reordr */
720 
721 
722 
723 /* ALGORITHM AS274.13 APPL. STATIST. (1992) VOL.41, NO.2 */
724 int gf_hdiag(double *xrow, int np, int nrbar, double *d, double *rbar, double *tol, int nreq, double *hii)
725 {
726  int i__1, i__2, ier=0, col, pos, row;
727  double d__1, sum, *wk;
728 
729  --tol;
730  --rbar;
731  --d;
732  --xrow;
733 
734  if(np < 1)
735  {
736  ier = 1;
737  }
738 
739  if(nrbar < np * (np - 1) / 2)
740  {
741  ier += 2;
742  }
743 
744  if(nreq > np)
745  {
746  ier += 4;
747  }
748 
749  if(ier)
750  {
751  return ier;
752  }
753 
754 
755 /* The elements of XROW.inv(RBAR).sqrt(D) are calculated and stored in WK. */
756  wk = -1 + (double *) malloc(np*sizeof(double));
757  *hii = 0;
758  i__1 = nreq;
759 
760  for(col=1;col<= i__1;++col)
761  {
762  if(sqrt(d[col]) <= tol[col])
763  {
764  wk[col] = 0;
765  }
766  else
767  {
768  i__2 = pos = col - 1;
769  sum = xrow[col];
770 
771  for(row = 1; row <= i__2; ++row)
772  {
773  sum -= wk[row] * rbar[pos];
774  pos += np - row - 1;
775  }
776 
777  d__1 = wk[col] = sum;
778  *hii += d__1 * d__1 / d[col];
779  }
780  }
781 
782  free(wk+1);
783 
784  return(0);
785 } /* gf_hdiag */
786 
787 
788 
789 
790 /* "print a upper triangular double matrix stored as a vector"
791  * The matrix is N x N, the vector has N*(N+1)/2 elements.
792  * Each element is formatted using width and precision.
793  * There are no sanity checks at all.
794  */
795 void gf_pr_utdm_v(double *x, int N, int width, int precision)
796 {
797  int pos=0, i, j, leavespace;
798  char s[100], fmt[100]; /* will be used in making printf() formats */
799  char buf[256];
800 
801  sprintf(fmt, "%%%d.%dg", width, precision);
802 
803  for(i=0;i<N;i++)
804  {
805  leavespace = i*width;
806  sprintf(s, "%%%ds", leavespace);
807  printf(buf, s, "");
808 
809  for(j=i;j<N;j++)
810  {
811  printf(buf, fmt, x[pos++]);
812  }
813 
814  printf("\n");
815  }
816 }
817 
818 
819 
820 double *gf_dvector(int l, int h)
821 {
822  double *block;
823  int size;
824 
825  size = h - l + 1;
826  block = (double *) malloc(sizeof(double)*size);
827 
828  if(block == NULL)
829  {
830  fprintf(stderr, "malloc failure in dvector()\n");
831 
832  return NULL;
833  }
834 
835  return(block-l);
836 }
837 
838 
839 
840 int *gf_ivector(int l, int h)
841 {
842  int *block, size;
843 
844  size = h - l + 1;
845  block = (int *) malloc(sizeof(int)*size);
846 
847  if(block == NULL)
848  {
849  fprintf(stderr, "malloc failure in ivector()\n");
850 
851  return NULL;
852  }
853 
854  return(block-l);
855 }
856 
857 
858 
859 double **gf_dmatrix(int rl, int rh, int cl, int ch)
860 {
861  double *block;
862  double **m;
863  int size, i, rowsize, numrows;
864 
865  rowsize = ch - cl + 1; /* #locations consumed by 1 row */
866  numrows = rh -rl + 1;
867  size = numrows*rowsize;
868  block = (double *) malloc((unsigned) sizeof(double)*size);
869 
870  if(block == NULL)
871  {
872  fprintf(stderr, "malloc failure in matrix allocation\n");
873 
874  return(NULL);
875  }
876  /* so we have the matrix. */
877 
878  /* Now for the row pointers */
879  m = (double **) malloc((unsigned) sizeof(double *)*numrows);
880 
881  if(m == NULL)
882  {
883  fprintf(stderr, "malloc failure in matrix allocation\n");
884 
885  return(NULL);
886  }
887  m -= rl; /* fixup m pointer so m[rl] == old m[0] */
888 
889  /* Finally, setup pointers to rows */
890  block -= cl;
891 
892  for(i=rl;i<=rh;i++)
893  {
894  m[i] = block; block += rowsize;
895  }
896 
897  return(m);
898 }
899 
900 
901 
902 void gf_putdvec(const char *s, double *x, int l, int h)
903 {
904  int i;
905  char buf[512];
906 
907  printf(buf, "Vector %-10s: \n", s);
908 
909  for(i=l;i<=h;i++)
910  {
911  printf(buf, " %d: %.4g \n", i, x[i]);
912  }
913 }
914 
915 
916 int dofitcurve(int cnt, double *xd, double *yd, int nd, double *c)
917 {
918  double **x, *y, *d, *rbar, *thetab, *xrow, sserr, *beta;
919  double *tol, *rss;
920  int i, j, nvars = nd + 1, nrbar = 200, *vorder, *lindep, error;
921  double xval;
922  char buf[256];
923  extern int debug;
924 
925  x = gf_dmatrix(0, cnt - 1, 0, nvars - 1);
926  y = gf_dvector(0, cnt - 1);
927  d = gf_dvector(0, nvars - 1);
928  rbar = gf_dvector(0, nrbar);
929  thetab = gf_dvector(0, nvars - 1);
930  xrow = gf_dvector(0, nvars - 1);
931  beta = gf_dvector(0, nvars - 1);
932  tol = gf_dvector(0, nvars - 1);
933  rss = gf_dvector(0, nvars - 1);
934  vorder = gf_ivector(0, nvars - 1);
935  lindep = gf_ivector(0, nvars - 1);
936 
937  for(i=0;i<nvars;i++)
938  {
939  vorder[i] = i;
940  }
941 
942  for(i=0;i<cnt;i++)
943  {
944  xval = xd[i];
945 
946  for (j=1;j<nvars;j++)
947  {
948  x[i][j - 1] = pow(xval, (double) j);
949  }
950 
951  y[i] = yd[i];
952  }
953 
954  error = gf_clear(nvars, nrbar, d, rbar, thetab, &sserr);
955 
956  if(error)
957  {
958  printf("as274c: clear() returned %d\n", error);
959  goto bustout;
960  }
961 
962  for (i=0; i<cnt; i++)
963  {
964  xrow[0] = 1; /* include constant */
965 
966  for(j=0;j<nvars-1;j++)
967  {
968  xrow[j+1] = x[i][j];
969  }
970 
971  error = gf_includ(nvars, nrbar, 1.0, xrow, y[i], d, rbar, thetab, &sserr);
972 
973  if(error)
974  {
975  printf("as274c: includ() returned %d at row %d\n", error, i);
976  goto bustout;
977  }
978  }
979 
980  error = gf_tolset(nvars, nrbar, d, rbar, tol);
981 
982  if(error)
983  {
984  printf("as274c: tolset() returned %d\n", error);
985  goto bustout;
986  }
987 
988  error = gf_sing(nvars, nrbar, d, rbar, thetab, &sserr, tol, lindep);
989 
990  if(error)
991  {
992  printf("as274c: sing() returned %d\n", error);
993  goto bustout;
994  }
995 
996  if(debug)
997  {
998  printf(buf, "\nSSerr = %17g\n", sserr);
999  }
1000 
1001  error = gf_regcf(nvars, nrbar, d, rbar, thetab, tol, beta, nvars);
1002 
1003  if(error)
1004  {
1005  printf("as274c: regcf() returned %d\n", error);
1006  goto bustout;
1007  }
1008 
1009  if(debug)
1010  {
1011  printf("\nVariable order:\n ");
1012 
1013  for(j=0;j<nvars;j++)
1014  {
1015  printf(buf, " %d ", vorder[j]);
1016  }
1017 
1018  printf("\n");
1019 
1020  gf_putdvec("Beta", beta, 0, nvars - 1);
1021  gf_putdvec("d", d, 0, nvars - 1);
1022 
1023  printf(buf, "rbar matrix:\n");
1024 
1025  gf_pr_utdm_v(rbar, nvars - 1, 13, 5);
1026  gf_putdvec("thetab", thetab, 0, nvars - 1);
1027  }
1028 
1029  for(j=0;j<nvars;j++)
1030  {
1031  c[j] = beta[j];
1032  }
1033 
1034 bustout:;
1035  free(x[0]);
1036  free(x);
1037  free(y);
1038  free(d);
1039  free(rbar);
1040  free(thetab);
1041  free(xrow);
1042  free(beta);
1043  free(tol);
1044  free(rss);
1045  free(vorder);
1046  free(lindep);
1047 
1048  return(0);
1049 }
int gf_sing(int np, int nrbar, double *d, double *rbar, double *thetab, double *sserr, double *tol, int *lindep)
Definition: grace_dofit.c:285
struct XBE_POS m1[]
Definition: obsmodes.c:81
void gf_inv(int np, int nrbar, double *rbar, int nreq, double *rinv)
Definition: grace_dofit.c:400
int first
Definition: dbase.c:106
int gf_clear(int np, int nrbar, double *d, double *rbar, double *thetab, double *sserr)
Definition: grace_dofit.c:184
int gf_regcf(int np, int nrbar, double *d, double *rbar, double *thetab, double *tol, double *beta, int nreq)
Definition: grace_dofit.c:215
int gf_cov(int np, int nrbar, double *d, double *rbar, int nreq, double *rinv, double *var, double *covmat, int dimcov, double *sterr)
Definition: grace_dofit.c:361
int debug
Definition: mailparse.c:29
int dofitcurve(int cnt, double *xd, double *yd, int nd, double *c)
Definition: grace_dofit.c:976
void gf_cor(int np, double *d, double *rbar, double *thetab, double *sserr, double *work, double *cormat, double *ycorr)
Definition: grace_dofit.c:457
double sum
Definition: beam.h:5
int gf_includ(int np, int nrbar, double w, double *xrow, double y, double *d, double *rbar, double *thetab, double *sserr)
Definition: grace_dofit.c:95
int * gf_ivector(int l, int h)
Definition: grace_dofit.c:898
#define N
Definition: gsl_try_2.c:67
void gf_putdvec(const char *s, double *x, int l, int h)
Definition: grace_dofit.c:960
struct XBE_POS m2[]
Definition: obsmodes.c:77
int gf_reordr(int np, int nrbar, int *vorder, double *d, double *rbar, double *thetab, double *rss, double *tol, int *list, int n, int pos1)
Definition: grace_dofit.c:714
void gf_pr_utdm_v(double *x, int N, int width, int precision)
Definition: grace_dofit.c:851
double ** gf_dmatrix(int rl, int rh, int cl, int ch)
Definition: grace_dofit.c:917
double * gf_dvector(int l, int h)
Definition: grace_dofit.c:878
int gf_hdiag(double *xrow, int np, int nrbar, double *d, double *rbar, double *tol, int nreq, double *hii)
Definition: grace_dofit.c:780
int gf_ss(int np, double *d, double *thetab, double *sserr, double *rss)
Definition: grace_dofit.c:341
int gf_pcorr(int np, int nrbar, double *d, double *rbar, double *thetab, double *sserr, int in, double *cormat, int dimc, double *ycorr)
Definition: grace_dofit.c:427
int gf_vmove(int np, int nrbar, int *vorder, double *d, double *rbar, double *thetab, double *rss, int from, int to, double *tol)
Definition: grace_dofit.c:536
#define m(i)
int gf_tolset(int np, int nrbar, double *d, double *rbar, double *tol)
Definition: grace_dofit.c:247