ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/JSOC/proj/rings/apps/rdutil.c
Revision: 1.3
Committed: Sat Aug 4 19:39:45 2012 UTC (11 years, 1 month ago) by rick
Content type: text/plain
Branch: MAIN
CVS Tags: Ver_6-4, Ver_9-1, Ver_8-8, Ver_8-2, Ver_8-3, Ver_8-0, Ver_8-1, Ver_8-6, Ver_8-7, Ver_8-4, Ver_8-5, Ver_7-1, Ver_7-0, Ver_8-10, Ver_8-11, Ver_8-12, Ver_9-0
Changes since 1.2: +94 -16 lines
Log Message:
modified for JSOC release 6.4

File Contents

# Content
1 /*
2 * rdutil.c
3 *
4 * library of utility functions for dealing with ring-diagram fit files
5 *
6 * autoweed_vel automatically weed velocities for inversions
7 * read_fit reads n, l, f, and d_f from a fit file
8 * read_fit_v reads n, l, f, d_f, u_i and d_ui from a fit file
9 *
10 * Bugs:
11 * read_fit() and read_fit_v() assume that the frequency error estimate
12 * is in column 5 of the fit table; for fit files produced with versions
13 * of rdfitc below 1.2, this is not the case
14 */
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <math.h>
18
19 /* some or all of the following declarations may be unnecessary */
20 /*
21 int interp_vel(int *n, double *l, double *f, double *ef, double *ux,
22 double *eux, double *uy, double *euy, int npts);
23 int interp_freq(int *n, double *l, double *f, double *ef, int npts,
24 int *ni, int *li, double *fi, double *efi, int *npts_out);
25 int freqdif(int *n1, int *n2, int *l1, double *l2, double *f1, double *f2,
26 double *ef1, double *ef2, int npts1, int npts2, int *n, int *l, double *f,
27 double *df, double *edf, int *npts);
28 int autoweed(int *l, int *n, double *f, double *df, double *edf, int *msk,
29 int npts);
30
31 int nearst(double xb, double x[], int ntab);
32 int divdif(double xb, double x[], double f[], int *nuse, int ntab,
33 double fb[], double aeps, double *dfb, double *ddfb);
34 int svdevl(int n, int m, double *u, double *v, double sigma[], int lu,
35 int lv, double b[], double reps);
36 int svd(int n, int m, double *a, double *v, double sigma[], int la, int lv);
37 int llsq(int n, int m, int k, double *x, int ix, double f[], double ef[],
38 double a[], double *u, double *v, int iu, int iv, double sigma[],
39 double y[], void (* phi) (int , double * , double * ), double reps,
40 double *chisq);
41 void line(int m, double *x, double *y);
42 */
43 /*
44 * The following have been commented out for dependencies and because they are
45 * not used by rdfitc (which only uses autoweed_vel())
46 * interp_vel
47 * interp_freq
48 * freqdif
49 * autoweed
50 */
51 int autoweed_vel (int *n, double *l, double *ux, double *uy, int *mask,
52 int npts) {
53 /*
54 * Returns 'mask' of length npts: mask[i] is False for rejected modes.
55 * Ux and Uy are weeded together. Values are rejected when their difference
56 * from the mean exceeds 5 (tol?) std. dev., both the mean and std dev
57 * being calculated over the central 3/5 of the l range for the order
58 */
59 const int maxn = 8;
60 const double tol = 5.0;
61
62 int i, j, offset;
63 int n_num[maxn];
64 double num;
65 double sumx, sumxx, sumy, sumyy, meanx, meany, stdx, stdy;
66 double range, uxmin, uxmax, uymin, uymax;
67 double lmin,lmax;
68
69 for (i=0; i<maxn; i++) n_num[i] = 0;
70 for (i=0; i<npts; i++)
71 if (n[i] < maxn) n_num[n[i]]++;
72
73 offset = 0;
74 for (i=0; i<maxn; i++) {
75 num = 0.0;
76 sumx = 0.0;
77 sumy = 0.0;
78 sumxx = 0.0;
79 sumyy = 0.0;
80 /* get l limits */
81 lmin = lmax = l[offset];
82 for (j=offset; j < n_num[i] + offset; j++) {
83 if (l[j] < lmin) lmin = l[j];
84 if (l[j] > lmax) lmax = l[j];
85 }
86 range = 0.2 * (lmax - lmin);
87 lmin += 2.0 * range;
88 lmax -= 2.0 * range;
89 for (j=offset; j < n_num[i] + offset; j++) {
90 if ((l[j] <= lmax) && (l[j] >= lmin)) {
91 sumx += ux[j];
92 sumxx += ux[j]*ux[j];
93 sumy += uy[j];
94 sumyy += uy[j]*uy[j];
95 num++;
96 }
97 }
98 meanx = sumx / num;
99 meany = sumy / num;
100 stdx = num*sumxx - sumx*sumx;
101 stdy = num*sumyy - sumy*sumy;
102 stdx /= (num * (num - 1));
103 stdy /= (num * (num - 1));
104 stdx = sqrt (stdx);
105 stdy = sqrt (stdy);
106 uxmin = meanx - 5.0 * stdx;
107 uxmax = meanx + 5.0 * stdx;
108 uymin = meany - 5.0 * stdy;
109 uymax = meany + 5.0 * stdy;
110
111 for (j=offset; j<n_num[i]+offset; j++) {
112 if (ux[j] <= uxmax && ux[j] >= uxmin &&
113 uy[j] <= uymax && uy[j] >= uymin) mask[j]=1;
114 else mask[j]=0;
115 }
116 offset +=n_num[i];
117 }
118 return 0;
119 }
120
121 int read_fit (FILE *fpt, int *npts, int **n, double **l, double **f,
122 double **ef) {
123 int i, nlines;
124 char buffer[8192];
125 if (ferror (fpt)) return -1;
126 if (feof (fpt)) rewind (fpt);
127
128 nlines = 0;
129 while (!feof(fpt)) {
130 fgets (buffer, 8192, fpt);
131 if (buffer[0] != '#' && !feof (fpt)) nlines++;
132 }
133 if (nlines == 0) return 1;
134
135 *n = (int *)malloc (nlines * sizeof (int));
136 *l = (double *)malloc (nlines * sizeof (double));
137 *f = (double *)malloc (nlines * sizeof (double));
138 *ef = (double *)malloc (nlines * sizeof (double));
139
140 rewind (fpt);
141
142 for (i=0; i<nlines; i++) {
143 fgets (buffer, 8192, fpt);
144 while (buffer[0] == '#') fgets( buffer, 8192, fpt);
145 sscanf (buffer, "%i %lf %*f %lf %lf", &(*n)[i], &(*l)[i], &(*f)[i],
146 &(*ef)[i]);
147 }
148 *npts = nlines;
149
150 return 0;
151 }
152
153 int read_fit_v (FILE *fpt, int *npts, int **n, double **l, double **f,
154 double **ef, double **ux, double **eux, double **uy, double **euy) {
155 int i, nlines;
156 char buffer[8192];
157 if (ferror (fpt)) return -1;
158 if (feof (fpt)) rewind (fpt);
159
160 nlines = 0;
161 while (!feof (fpt)) {
162 fgets (buffer, 8192, fpt);
163 if (buffer[0] != '#' && !feof (fpt)) nlines++;
164 }
165 if (nlines == 0) return 1;
166
167 *n = (int *)realloc (*n, nlines * sizeof (int));
168 *l = (double *)realloc (*l, nlines * sizeof (double));
169 *f = (double *)realloc (*f, nlines * sizeof (double));
170 *ef = (double *)realloc (*ef, nlines * sizeof (double));
171 *ux = (double *)realloc (*ux, nlines * sizeof (double));
172 *eux = (double *)realloc (*eux, nlines * sizeof (double));
173 *uy = (double *)realloc (*uy, nlines * sizeof (double));
174 *euy = (double *)realloc (*euy, nlines * sizeof (double));
175
176 rewind (fpt);
177
178 for (i=0; i<nlines; i++) {
179 fgets (buffer, 8192, fpt);
180 while (buffer[0] == '#') fgets (buffer, 8192, fpt);
181 sscanf (buffer, "%i %lf %*f %lf %lf %lf %lf %lf %lf", &(*n)[i], &(*l)[i],
182 &(*f)[i], &(*ef)[i], &(*ux)[i], &(*eux)[i], &(*uy)[i], &(*euy)[i]);
183 }
184 *npts = nlines;
185
186 return 0;
187 }
188 /*
189 int interp_vel(int *n, double *l, double *f, double *ef, double *ux,
190 double *eux, double *uy, double *euy, int npts) {
191 */
192 /*
193 Function - interp
194 Takes power spectra fit parameters, and interpolates them to integer l.
195 Data are returned in the input arrays - **data is overwritten!**
196 */
197 /*
198 int i, j, nuse, ierr, offset=0;
199 int n_num[13];
200 double fb[10], ll;
201 double dfb, ddfb, aeps=1e-7;
202 double *inp_l, *inp_f, *inp_ef, *inp_ux, *inp_uy, *inp_eux, *inp_euy;
203 FILE * outBug;
204
205 // count number of frequencies for each n
206 // note that it is assumed that all frequencies for each
207 // n are grouped together in the arrays
208 for(i=0; i<13; i++) n_num[i]=0;
209 for(i=0; i < npts; i++) {
210 n_num[n[i]] ++;
211 }
212
213 inp_l=(double*) malloc(npts*sizeof(double));
214 inp_f=(double*) malloc(npts*sizeof(double));
215 inp_ef=(double*) malloc(npts*sizeof(double));
216 inp_ux=(double*) malloc(npts*sizeof(double));
217 inp_uy=(double*) malloc(npts*sizeof(double));
218 inp_eux=(double*) malloc(npts*sizeof(double));
219 inp_euy=(double*) malloc(npts*sizeof(double));
220 // loop over n
221 // outBug=fopen("tesbug","w");
222 for(i=0; i < 10; i++) {
223 for(j=0;j<npts;j++) {
224 inp_l[j]=0.0;
225 inp_f[j]=0.0;
226 inp_ef[j]=0.0;
227 inp_ux[j]=0.0;
228 inp_uy[j]=0.0;
229 inp_eux[j]=0.0;
230 inp_euy[j]=0.0;
231 }
232 for(j=0;j<n_num[i];j++) {
233 inp_l[j]=l[j+offset];
234 inp_f[j]=f[j+offset];
235 inp_ef[j]=ef[j+offset];
236 inp_ux[j]=ux[j+offset];
237 inp_uy[j]=uy[j+offset];
238 inp_eux[j]=eux[j+offset];
239 inp_euy[j]=euy[j+offset];
240 }
241 for(j=0;j<n_num[i];j++) {
242 ll=(int)(inp_l[j]+0.5);
243 nuse=3;
244 ierr=divdif(ll, inp_l, inp_f, &nuse,
245 n_num[i], fb, aeps, &dfb, &ddfb);
246 f[j+offset]=fb[nuse];
247 nuse=3;
248 ierr=divdif(ll, inp_l, inp_ef, &nuse,
249 n_num[i], fb, aeps, &dfb, &ddfb);
250 ef[j+offset]=fb[nuse];
251 nuse=3;
252 ierr=divdif(ll, inp_l, inp_ux, &nuse,
253 n_num[i], fb, aeps, &dfb, &ddfb);
254 ux[j+offset]=fb[nuse];
255 nuse=3;
256 ierr=divdif(ll, inp_l, inp_uy, &nuse,
257 n_num[i], fb, aeps, &dfb, &ddfb);
258 uy[j+offset]=fb[nuse];
259 nuse=3;
260 ierr=divdif(ll, inp_l, inp_eux, &nuse,
261 n_num[i], fb, aeps, &dfb, &ddfb);
262 eux[j+offset]=fb[nuse];
263 nuse=3;
264 ierr=divdif(ll, inp_l, inp_euy, &nuse,
265 n_num[i], fb, aeps, &dfb, &ddfb);
266 euy[j+offset]=fb[nuse];
267 l[j+offset]=ll;
268 }
269 offset+=n_num[i];
270 }
271
272 return 0;
273 }
274 */
275 /*
276 int interp_freq(int *n, double *l, double *f, double *ef, int npts,
277 int *ni, int *li, double *fi, double *efi, int *npts_out) {
278 int i, j, nn, ll, nmin, nmax, this_npts, nuse;
279 double *this_l, *this_f, *this_ef, all, fb[5];
280 double reps, dfb, ddfb, ff, error;
281
282 this_l = (double*) malloc(npts*sizeof(double));
283 this_f = (double*) malloc(npts*sizeof(double));
284 this_ef = (double*) malloc(npts*sizeof(double));
285
286 *npts_out = 0;
287 nmin = 100;
288 nmax = 0;
289 for(i=0; i<npts; i++) {
290 if(n[i] < nmin) nmin = n[i];
291 if(n[i] > nmax) nmax = n[i];
292 }
293 for(nn=nmin; nn<=nmax; nn++) {
294 j = 0;
295 for(i=0; i<npts; i++) {
296 if(n[i]==nn) {
297 this_l[j] = l[i];
298 this_f[j] = f[i];
299 this_ef[j] = ef[i];
300 j++;
301 }
302 }
303 this_npts = j;
304 j = *npts_out;
305 //printf("%i %i\n",this_npts, *npts_out);
306 for(i=0; i<this_npts; i++) {
307 ll = (int) this_l[i] + 0.5;
308 all = (double) ll; // cast back to double for function argument
309 nuse = 3;
310 reps = 1.0e-7;
311 //printf("got here\n");
312 divdif(all, this_l, this_f, &nuse, this_npts, fb, reps, &dfb, &ddfb);
313 ff = fb[nuse];
314 nuse = 3;
315 divdif(all, this_l, this_ef, &nuse, this_npts, fb, reps, &dfb, &ddfb);
316 error = fb[nuse];
317 //printf("%i %i %f %f\n",nn,ll,ff,error);
318 if(error>0) {
319 ni[j] = nn;
320 li[j] = ll;
321 fi[j] = ff;
322 efi[j] = error;
323 j++;
324 }
325 }
326 //printf("%i\n",j);
327 *npts_out = j;
328 }
329
330 return 0;
331 }
332 */
333 /*
334 int freqdif(int *n1, int *n2, int *l1, double *l2, double *f1, double *f2,
335 double *ef1, double *ef2, int npts1, int npts2, int *n, int *l, double *f,
336 double *df, double *edf, int *npts) {
337 int i, j, nn, ll, *index, nmin, nmax, lmin, lmax, this_npts, ind;
338 int nuse;
339 double *this_l, *this_f, *this_ef, all, fb[5], dfb, ddfb, reps;
340 double ff, error;
341
342 *npts = 0;
343
344 this_l = (double*) malloc(npts2*sizeof(double));
345 this_f = (double*) malloc(npts2*sizeof(double));
346 this_ef = (double*) malloc(npts2*sizeof(double));
347
348 nmin = n1[0];
349 nmax = n1[0];
350 // lmin = (int) l2[0]+0.5;
351 // lmax = (int) l2[0]+0.5;
352 for(i=1; i<npts1; i++) {
353 if(n1[i] < nmin) nmin = n1[i];
354 if(n1[i] > nmax) nmax = n1[i];
355 // if(l2[i] < lmin) lmin = (int) l2[i]+0.5;
356 // if(l2[i] > lmax) lmax = (int) l2[i]+0.5;
357 }
358
359 // index = (int*) malloc((nmax-nmin)*(lmax-lmin)*sizeof(int));
360 // for(i=0; i<(nmax-nmin)*(lmax-lmin); i++) index[i] = -1;
361 // for(i=0; i<npts2; i++) {
362 // ll = (int) l2[i]+0.5;
363 // index[n2[i]*(lmax-lmin)+ll-lmin] = i;
364 // }
365
366 for(nn=nmin; nn<=nmax; nn++) {
367 j = 0;
368 lmin = 10000;
369 lmax = 0;
370 for(i=0; i<npts2; i++) {
371 if(n2[i] == nn) {
372 this_l[j] = l2[i];
373 this_f[j] = f2[i];
374 this_ef[j] = ef2[i];
375 if(lmin > l2[i]) lmin = (int) l2[i]+0.5;
376 if(lmax < l2[i]) lmax = (int) l2[i]+0.5;
377 j++;
378 }
379 }
380 this_npts = j;
381 //printf("this_npts = %i\n", this_npts);
382 j = *npts;
383 for(i=0; i<npts1; i++) {
384 // ind = index[n1[i]*(lmax-lmin)+l1[i]-lmin];
385 // if(ind>=0) {
386 if(n1[i] == nn && l1[i] >= lmin && l1[i] <= lmax) {
387 //ll = (int) this_l[i] + 0.5;
388 ll = l1[i];
389 all = (double) ll; // cast back to double for function argument
390 nuse = 3;
391 reps = 1.0e-7;
392 divdif(all, this_l, this_f, &nuse, this_npts, fb, reps, &dfb, &ddfb);
393 ff = fb[nuse];
394 nuse = 3;
395 divdif(all, this_l, this_ef, &nuse, this_npts, fb, reps, &dfb, &ddfb);
396 error = fb[nuse];
397 if(error>0.0) {
398 n[j] = nn;
399 l[j] = ll;
400 f[j] = f1[i];
401 df[j] = f1[i] - ff;
402 edf[j] = sqrt(ef1[i]*ef1[i]+error*error);
403 //printf("%i %i %i %f %f %f\n",j, n[j], l[j], f[j], df[j], edf[j]);
404 j++;
405 }
406 }
407 }
408 *npts = j;
409 //printf("%i\n",*npts);
410 }
411
412 return 0;
413 }
414 */
415 void line (int m, double *x, double *y) {
416 y[0] = x[0];
417 y[1] = 1.0;
418 return;
419 }
420 /*
421 int autoweed(int *l, int *n, double *f, double *df, double *edf, int *msk,
422 int npts) {
423 int avglen = 4;
424 double tol = 4.0;
425 double delnu = 50.0;
426 int i, j, nn, this_npts, llim, ulim, offset;
427 int data_range[2], *this_l;
428 double *this_f, *this_df, *this_edf, *slopes, *a, *u, *y;
429 double v[4], sigma[2], chisq;
430 double mean, std;
431
432 this_l = (int*) malloc(npts*sizeof(int));
433 this_f = (double*) malloc(npts*sizeof(double));
434 this_df = (double*) malloc(npts*sizeof(double));
435 this_edf = (double*) malloc(npts*sizeof(double));
436 slopes = (double*) malloc(npts*sizeof(double));
437 a = (double*) malloc(avglen*sizeof(double));
438 u = (double*) malloc(2*avglen*sizeof(double));
439 y = (double*) malloc(avglen*sizeof(double));
440 offset = 0;
441 for(i=0; i<npts; i++) msk[i] = 0;
442 for(nn=0; nn<7; nn++) {
443 j = 0;
444 mean = 0.0;
445 std = 0.0;
446 for(i=0; i<npts; i++) {
447 if(n[i] == nn) {
448 this_l[j] = l[i];
449 this_f[j] = f[i];
450 this_df[j] = df[i];
451 this_edf[j] = edf[i];
452 j++;
453 }
454 }
455 this_npts = j;
456 if(this_npts > avglen + 5) {
457 data_range[0] = (int) 2*this_npts/10.;
458 data_range[1] = (int) 8*this_npts/10.;
459 for(i=0; i<this_npts-avglen; i++) {
460 llsq(avglen, 2, 1, &this_f[i], 1, &this_df[i], &this_edf[i], a, u,
461 v, 2, 2, sigma, y, *line, 1.0e-6, &chisq);
462 slopes[i] = a[0];
463 //printf("%i %f\n",nn,a[0]);
464 mean += a[0];
465 }
466 mean /= (double) this_npts;
467 for(i=0; i<this_npts-avglen; i++) std += (slopes[i]-mean)*(slopes[i]-mean);
468 std /= (double) this_npts;
469 std = sqrt(std);
470 // printf("%i %i %i\n",data_range[0], data_range[1], this_npts/2);
471 llim = data_range[0];
472 ulim = data_range[1];
473 while(llim > 0) {
474 if( fabs(slopes[llim]-mean)/std > tol) break;
475 llim--;
476 }
477 while(ulim<this_npts-avglen-1) {
478 if( fabs(slopes[ulim]-mean)/std > tol) break;
479 ulim++;
480 }
481 i = this_npts/2;
482 while(i>0) {
483 if(this_f[i]-this_f[i-1] > delnu) break;
484 i--;
485 }
486 if(i > llim) llim = i;
487 i = this_npts/2;
488 while(i<this_npts) {
489 if(this_f[i]-this_f[i-1] > delnu) break;
490 i++;
491 }
492 if(i < ulim) ulim = i;
493 printf("%i %i %i %i\n",nn,this_npts,llim,ulim);
494 for(i=offset+llim; i<offset+ulim; i++) msk[i] = 1;//i<this_npts+offset-ulim; i++) msk[i] = 1;
495 offset += this_npts;
496 }
497 }
498
499 return 0;
500 }
501 */
502
503 int nearst (double xb, double x[], int ntab) {
504 int low, igh, mid;
505
506 low=0; igh=ntab-1;
507 if((xb < x[low]) != (xb < x[igh]) ) {
508
509 /* If the point is within the range of table, then locate it by bisection */
510
511 while(igh-low > 1) {
512 mid=(low+igh)/2;
513 if((xb < x[mid]) == (xb < x[low])) low=mid;
514 else igh=mid;
515 }
516 }
517
518 if(fabs(xb-x[low]) < fabs(xb-x[igh])) return low;
519 else return igh;
520 }
521
522 int divdif(double xb, double x[], double f[], int *nuse, int ntab,
523 double fb[], double aeps, double *dfb, double *ddfb) {
524 int i,j,k,next,in,ip,nit,ier, nmax=10;
525 double err,px,dpx,ddpx,xn[11],xd[11];
526
527 /* Find the nearest point */
528
529 next=nearst(xb,x,ntab);
530 fb[1]=f[next];
531 xd[1]=f[next];
532 xn[1]=x[next];
533 ier=0;
534 px=1.0;
535
536 /* Initialisation for the derivatives */
537
538 *dfb=0.0; *ddfb=0.0;
539 dpx=0.0; ddpx=0.0;
540
541 /* Points between IN and IP are used for interpolation */
542
543 ip=next; in=next;
544
545 /* Maximum number of points to be used for interpolation */
546 nit=*nuse; if(nmax<nit) nit=nmax; if(ntab<nit) nit=ntab;
547 if(*nuse>nmax || *nuse>ntab) ier=22;
548 if(*nuse<1) {
549 ier=21;
550 nit=6; if(nmax<nit) nit=nmax; if(ntab<nit) nit=ntab;
551 }
552 *nuse=1;
553
554 /* Calculate successive interpolation polynomial */
555 for(j=2; j<=nit; ++j) {
556 /* Choose the next nearest point to XB */
557 if(in<=0 ) {
558 ip=ip+1; next=ip;
559 }
560 else if(ip >= ntab-1) {
561 in=in-1; next=in;
562 }
563 else if(fabs(xb-x[ip+1]) < fabs(xb-x[in-1]) ) {
564 ip=ip+1; next=ip;
565 }
566 else {
567 in=in-1; next=in;
568 }
569
570 /* Calculating the divided differences */
571 xd[j]=f[next];
572 xn[j]=x[next];
573 for(k=j-1; k>=1; --k) xd[k]=(xd[k+1]-xd[k])/(xn[j]-xn[k]);
574
575 /* Calculating the derivatives */
576 ddpx=ddpx*(xb-xn[j-1])+2.*dpx;
577 dpx=dpx*(xb-xn[j-1])+px;
578 *dfb = *dfb+dpx*xd[1];
579 *ddfb = *ddfb+ddpx*xd[1];
580
581 px=px*(xb-xn[j-1]);
582 err=xd[1]*px;
583 fb[j]=fb[j-1]+err;
584 *nuse=j;
585
586 if(fabs(err) < aeps) return ier;
587 }
588 return 23;
589 }
590
591 int svd (int n, int m, double *a, double *v, double sigma[], int la, int lv) {
592 int i, j, k, l, itr, ier, itmax=30;
593 double f, g, h, rmax, s, r1, r2, c, x, y, z, aeps, eps=1.e-16;
594 // double *e;
595 double e[2];
596
597 if(n>m || n<=0 || m<=0 || n>la || n>lv) return 105;
598 ier=0;
599
600 /* Reduction to Bidiagonal form using Householder transformations */
601 g=0.0; rmax=0.0;
602 // e=(double *) calloc(n, sizeof(double));
603
604 for(i=0; i<n; ++i) {
605 /* Off-diagonal elements of bidiagonal form */
606 e[i]=g;
607 s=0.0;
608 for(j=i; j<m; ++j) s=s+a[i+j*la]*a[i+j*la];
609 if(s <= 0.0) {
610 /* transformation not required */
611 g=0.0;
612 }
613 else {
614 f= a[i+i*la];
615 g=sqrt(s);
616 if(f>=0.0) g=-g;
617 h=f*g-s;
618 a[i+i*la] = f-g;
619
620 for(j=i+1; j<n; ++j) {
621 s=0.0;
622 for(k=i; k<m; ++k) s=s+a[i+k*la]*a[j+k*la];
623 f=s/h;
624 for(k=i; k<m; ++k) a[j+k*la]= a[j+k*la]+f*a[i+k*la];
625 }
626 }
627
628 /* Diagonal elements of bidiagonal form */
629 sigma[i]=g;
630 s=0.0;
631 for(j=i+1; j<n; ++j) s=s+a[j+i*la]*a[j+i*la];
632
633 if(s<= 0.0) g=0.0;
634 else {
635 f= a[i*la+(i+1)];
636 g=sqrt(s);
637 if(f>= 0.0) g=-g;
638 h=f*g-s;
639 a[i*la+(i+1)]=f-g;
640 for(j=i+1; j<n; ++j) e[j]=a[j+i*la]/h;
641
642 for(j=i+1; j<m; ++j) {
643 s=0.0;
644 for(k=i+1; k<n; ++k) s=s+a[k+j*la]*a[k+i*la];
645 for(k=i+1; k<n; ++k) a[k+j*la] = a[k+j*la]+s*e[k];
646 }
647 }
648 r1=fabs(sigma[i])+fabs(e[i]);
649 if(r1 > rmax) rmax=r1;
650 }
651
652 /* Accumulation of right hand transformation in array V */
653 for(i=n-1; i>=0; --i) {
654 if(g != 0.0) {
655 h=g*a[i*la+(i+1)];
656 for(j=i+1; j<n; ++j) v[i+j*lv]=a[j+i*la]/h;
657
658 for(j=i+1; j<n; ++j) {
659 s=0.0;
660 for(k=i+1; k<n; ++k) s=s+a[k+i*la]*v[j+k*lv];
661 for(k=i+1; k<n; ++k) v[j+k*lv]=v[j+k*lv]+s*v[i+k*lv];
662 }
663 }
664
665 for(j=i+1; j<n; ++j) {
666 v[j+i*lv]=0.0; v[i+j*lv]=0.0;
667 }
668 v[i+i*lv]=1;
669 g= e[i];
670 }
671
672 /* Accumulation of left hand transformation overwritten on matrix A */
673 for(i=n-1; i>=0; --i) {
674 g=sigma[i];
675 for(j=i+1; j<n; ++j) a[j+i*la]=0.0;
676 if(g != 0.0) {
677 h=g*a[i+i*la];
678
679 for(j=i+1; j<n; ++j) {
680 s=0.0;
681 for(k=i+1; k<m; ++k) s=s+a[i+k*la]*a[j+k*la];
682 f=s/h;
683 for(k=i; k<m; ++k) a[j+k*la]=a[j+k*la]+f*a[i+k*la];
684 }
685
686 for(j=i; j<m; ++j) a[i+j*la]=a[i+j*la]/g;
687 }
688 else {
689 for(j=i; j<m; ++j) a[i+j*la]=0.0;
690 }
691 a[i+i*la] = a[i+i*la]+1;
692 }
693
694 /* Diagonalisation of the bidiagonal form */
695 aeps=eps*rmax;
696 /* Loop over the singular values */
697 for(k=n-1; k>=0; --k) {
698 /* The QR transformation */
699 for(itr=1; itr<=itmax; ++itr) {
700
701 /* Test for splitting */
702 for(l=k; l>=0; --l) {
703 if(fabs(e[l]) < aeps) goto split;
704 if(fabs(sigma[l-1]) < aeps) break;
705 }
706
707 /* cancellation of E[L] if L>1 */
708 c=0.0; s=1.0;
709 for(i=l; i<=k; ++i) {
710 f=s*e[i];
711 e[i] = c*e[i];
712 if(fabs(f) < aeps) goto split;
713 g=sigma[i];
714 sigma[i]=sqrt(f*f+g*g);
715 c=g/sigma[i];
716 s=-f/sigma[i];
717
718 for(j=0; j<m; ++j) {
719 r1= a[j*la+(l-1)];
720 r2= a[i+j*la];
721 a[j*la+(l-1)]=r1*c+r2*s;
722 a[i+j*la]=c*r2-s*r1;
723 }
724 }
725
726 split: z=sigma[k];
727 if(l == k) {
728 /* QR iteration has converged */
729 if(z < 0.0) {
730 sigma[k] = -z;
731 for(j=0; j<n; ++j) v[k+j*lv]=-v[k+j*lv];
732 }
733 break;
734 }
735
736 if(itr==itmax) {ier=12; break;}
737
738 /* calculating shift from bottom 2x2 minor */
739 x=sigma[l];
740 y=sigma[k-1];
741 g=e[k-1];
742 h=e[k];
743 f=((y-z)*(y+z)+(g-h)*(g+h))/(2.*h*y);
744 g=sqrt(1.+f*f);
745 if(f < 0.0) g=-g;
746 f=((x-z)*(x+z)+h*(y/(f+g)-h))/x;
747
748 /* next QR transformation */
749 c=1.0; s=1.0;
750 /* Given's rotation */
751 for(i=l+1; i<=k; ++i) {
752 g=e[i];
753 y=sigma[i];
754 h=s*g;
755 g=c*g;
756 e[i-1]=sqrt(f*f+h*h);
757 c=f/e[i-1];
758 s=h/e[i-1];
759 f=c*x+s*g;
760 g=c*g-s*x;
761 h=s*y;
762 y=c*y;
763
764 for(j=0; j<n; ++j) {
765 x=v[j*lv+(i-1)];
766 z=v[i+j*lv];
767 v[j*lv+(i-1)]=c*x+s*z;
768 v[i+j*lv]=c*z-s*x;
769 }
770
771 sigma[i-1]=sqrt(f*f+h*h);
772 if(sigma[i-1] != 0.0) {
773 c=f/sigma[i-1];
774 s=h/sigma[i-1];
775 }
776 f=c*g+s*y;
777 x=c*y-s*g;
778 for(j=0; j<m; ++j) {
779 y= a[j*la+(i-1)];
780 z= a[i+j*la];
781 a[j*la+(i-1)] = c*y+s*z;
782 a[i+j*la] = c*z-s*y;
783 }
784 }
785
786 e[l]=0.0;
787 e[k]=f;
788 sigma[k]=x;
789 }
790 }
791 // free(e);
792 return ier;
793 }
794
795 int svdevl(int n, int m, double *u, double *v, double sigma[], int lu,
796 int lv, double b[], double reps)
797
798 {
799 int i,j;
800 double smax, aeps, s;
801 double *wk;
802
803 /* Finding the largest singular value */
804 smax=0.0;
805 for(i=0; i<n; ++i)
806 if(sigma[i] > smax) smax=sigma[i];
807
808 aeps=smax*reps;
809 wk=(double *)calloc(n, sizeof(double));
810 for(i=0; i<n; ++i) {
811 s=0.0;
812 /* Only SIGMA[I] > AEPS contribute to the solution */
813 if(sigma[i] > aeps) {
814 for(j=0; j<m; ++j) s=s+b[j]*u[i+j*lu];
815 s=s/sigma[i];
816 }
817 wk[i]=s;
818 }
819
820 for(i=0; i<n; ++i) {
821 s=0.0;
822 for(j=0; j<n; ++j) s=s+v[j+i*lv]*wk[j];
823 b[i]=s;
824 }
825 free(wk);
826 return 0;
827 }
828
829 int llsq(int n, int m, int k, double *x, int ix, double f[], double ef[],
830 double a[], double *u, double *v, int iu, int iv, double sigma[],
831 double y[], void (* phi) (int , double * , double * ), double reps,
832 double *chisq)
833
834 {
835 int i,j,ier;
836 double s1;
837 // double *wk;
838 double wk[2];
839
840 if(m>n || m<=0 || n<=0 || k>ix) return 606;
841
842 // wk=(double *) calloc(m, sizeof(double));
843 /* Setting up the design matrix and the RHS */
844 for(i=0; i<n; ++i) {
845 if(ef[i]<=0.0) {/*free(wk); */return 607;}
846 a[i]=f[i]/ef[i];
847 phi(m,&x[i*ix],wk);
848 for(j=0; j<m; ++j) u[j+i*iu]=wk[j]/ef[i];
849 }
850
851 ier=svd(m,n,u,v,sigma,iu,iv);
852 if(ier>100) {/*free(wk);*/ return ier;}
853
854 /* Calculate the least squares solution */
855 ier=svdevl(m,n,u,v,sigma,iu,iv,a,reps);
856
857 /* Computing the \chi^2 from fitted coefficients */
858 *chisq=0.0;
859 for(i=0; i<n; ++i) {
860 phi(m,&x[i*ix],wk);
861 s1=0.0;
862 for(j=0; j<m; ++j) s1=s1+a[j]*wk[j];
863 y[i]=s1;
864 s1=(f[i]-y[i])/ef[i];
865 *chisq=(*chisq)+s1*s1;
866 }
867
868 // free(wk);
869 return 0;
870 }
871
872 int interp_vel (int *n, double *l, double *f, double *ef, double *ux,
873 double *eux, double *uy, double *euy, int npts) {
874 /*
875 Takes power spectra fit parameters, and interpolates them to integer l.
876 Data are returned in the input arrays - **data is overwritten!**
877 */
878 int i, j, nuse, ierr, offset=0;
879 int n_num[13];
880 double fb[10], ll;
881 double dfb, ddfb, aeps=1e-7;
882 double *inp_l, *inp_f, *inp_ef, *inp_ux, *inp_uy, *inp_eux, *inp_euy;
883 /* count number of frequencies for each n
884 N.B. It is assumed that all frequencies for each n
885 are grouped together in the arrays
886 */
887 for (i=0; i < 13; i++) n_num[i] = 0;
888 for (i=0; i < npts; i++) if (n[i] < 13) n_num[n[i]]++;
889
890 inp_l = (double *) malloc (npts*sizeof(double));
891 inp_f = (double *) malloc (npts*sizeof(double));
892 inp_ef = (double *) malloc (npts*sizeof(double));
893 inp_ux = (double *) malloc (npts*sizeof(double));
894 inp_uy = (double *) malloc (npts*sizeof(double));
895 inp_eux = (double *) malloc (npts*sizeof(double));
896 inp_euy = (double *) malloc (npts*sizeof(double));
897 /* loop over n */
898 for (i=0; i < 10; i++) {
899 for (j=0; j<npts; j++) {
900 inp_l[j] = 0.0;
901 inp_f[j] = 0.0;
902 inp_ef[j] = 0.0;
903 inp_ux[j] = 0.0;
904 inp_uy[j] = 0.0;
905 inp_eux[j] = 0.0;
906 inp_euy[j] = 0.0;
907 }
908 for(j=0; j<n_num[i]; j++) {
909 inp_l[j] = l[j+offset];
910 inp_f[j] = f[j+offset];
911 inp_ef[j] = ef[j+offset];
912 inp_ux[j] = ux[j+offset];
913 inp_uy[j] = uy[j+offset];
914 inp_eux[j] = eux[j+offset];
915 inp_euy[j] = euy[j+offset];
916 }
917 for (j = 0; j<n_num[i]; j++) {
918 ll = (int)(inp_l[j]+0.5);
919 nuse = 3;
920 ierr = divdif (ll, inp_l, inp_f, &nuse, n_num[i], fb, aeps, &dfb, &ddfb);
921 f[j+offset] = fb[nuse];
922 nuse = 3;
923 ierr = divdif (ll, inp_l, inp_ef, &nuse, n_num[i], fb, aeps, &dfb, &ddfb);
924 ef[j+offset] = fb[nuse];
925 nuse = 3;
926 ierr = divdif (ll, inp_l, inp_ux, &nuse, n_num[i], fb, aeps, &dfb, &ddfb);
927 ux[j+offset] = fb[nuse];
928 nuse = 3;
929 ierr = divdif (ll, inp_l, inp_uy, &nuse, n_num[i], fb, aeps, &dfb, &ddfb);
930 uy[j+offset] = fb[nuse];
931 nuse = 3;
932 ierr = divdif (ll, inp_l, inp_eux, &nuse, n_num[i], fb, aeps, &dfb, &ddfb);
933 eux[j+offset] = fb[nuse];
934 nuse = 3;
935 ierr = divdif (ll, inp_l, inp_euy, &nuse, n_num[i], fb, aeps, &dfb, &ddfb);
936 euy[j+offset] = fb[nuse];
937 l[j+offset] = ll;
938 }
939 offset += n_num[i];
940 }
941 free (inp_l);
942 free (inp_f);
943 free (inp_ef);
944 free (inp_ux);
945 free (inp_uy);
946 free (inp_eux);
947 free (inp_euy);
948
949 return 0;
950 }