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