00001
00002
00003
00004
00005
00006 #include <stdlib.h>
00007 #include <stdio.h>
00008 #include <string.h>
00009 #include <math.h>
00010
00011 extern void dsytrf_ (char *, int *, double *, int*, int *, double *, int *,
00012 int *);
00013
00014 extern void dsytrs_ (char *, int *, int *, double *, int *, int *, double *,
00015 int *, int *);
00016
00017 extern void solve_ (int *, int *, int *, int *, double *, double *,
00018 int *, int *, int *);
00019
00020 extern void fwidth_ (int *, int*, int *, double *, double *, double *, int *);
00021
00022 int solve (int la, int lb, int norder, int cols, double *a, double *b) {
00023 double *work;
00024 static int *ipiv = NULL;
00025 int n, lda, lwork, info, nrhs, ldb;
00026 static int last = 0, optsize;
00027 char uplo;
00028
00029 uplo = 'U';
00030 n = norder;
00031 lda = la;
00032 if (norder != last) {
00033 ipiv = (int *)realloc (ipiv, norder * sizeof (int));
00034 lwork = -1;
00035 work = (double *)malloc (sizeof (double));
00036 dsytrf_ (&uplo, &n, a, &lda, ipiv, work, &lwork, &info);
00037 if (info) {
00038 fprintf (stderr, "Error in solve():\n");
00039 fprintf (stderr, " initialization call to dsytrf_ returned %d\n", info);
00040 return info;
00041 }
00042 optsize = work[0];
00043 fprintf (stderr, " initialization call to dsytrf_ for order %d returned %f\n",
00044 norder, work[0]);
00045 free (work);
00046 uplo = 'U';
00047 n = norder;
00048 lda = la;
00049 last = norder;
00050 }
00051 lwork = optsize;
00052 work = (double *)malloc (lwork * sizeof (double));
00053 dsytrf_ (&uplo, &n, a, &lda, ipiv, work, &lwork, &info);
00054 if (info) {
00055 fprintf (stderr, "Error in solve():\n");
00056 fprintf (stderr, " call to dsytrf_ returned %d\n", info);
00057 fprintf (stderr, "LDA = %d (%d), N = %d (%d)\n", lda, la, n, norder);
00058 free (work);
00059 return info;
00060 }
00061
00062 uplo = 'U';
00063 n = norder;
00064 nrhs = cols;
00065 lda = la;
00066 ldb = lb;
00067 dsytrs_ (&uplo, &n, &nrhs, a, &lda, ipiv, b, &ldb, &info);
00068 if (info) {
00069 fprintf (stderr, "Error in solve():\n");
00070 fprintf (stderr, " call to dsytrs_ returned %d\n", info);
00071 }
00072
00073 free (work);
00074 return info;
00075 }
00076
00077 int ola_xy (double *dl_inp, int *n_inp, double *f_inp, double *ux_inp,
00078 double *euxinp, double *uy_inp, double *euyinp, int nmodes, char *filek1,
00079 double *x0, double *rcgx, double *rcgy, double *quartx, double *quarty,
00080 double *solnx, double *solny, double *errx, double *erry, char *filker,
00081 char *filcoef, int qave, int qcoef, int verbose, double ob, double oe,
00082 int num, double beg, double endd, double amu) {
00083 FILE *lun19, *lun21, *lun27, *lun29, *lun37;
00084 double *ov1, *cov, *suml, *vv1x, *vv1y;
00085 static double *aa1x = NULL, *aa1y = NULL;
00086 static double *avccx = NULL, *avccy= NULL;
00087 static double *avcx = NULL, *avcy = NULL, *cencx = NULL, *cency = NULL;
00088 static double *ckintx = NULL, *ckinty = NULL;
00089 double *ctil1x = NULL, *ctil1y = NULL, *ctil2x = NULL, *ctil2y = NULL;
00090 static double *rad = NULL, *fakc = NULL, *rl = NULL;
00091 static double *om = NULL, *dom = NULL, *error = NULL, *weight = NULL;
00092
00093
00094
00095
00096 double freq[3000][50][2], err[3000][50][2];
00097 double fdif[3000][50];
00098 double dthcx[3], dthcy[3];
00099 double dif1, dif2, erri1, erri2, sume1, sume2, sumcx, sumcy;
00100 double cc, dx, ooo, ot;
00101 double sum1, sum2, sum3, sa, sb, sc, term, sumccx, sumccy;
00102 double sumc1x, sumc2x, sumc1y, sumc2y;
00103 double sum1x, er1x, s1x, sum1y, er1y, s1y;
00104 float *ak;
00105 static float *rd = NULL;
00106 float rs, rms;
00107 static int *n = NULL, *ipiv = NULL;
00108 int nmode, np, nsp, numker, nktmp, ntab, nmdtmp;
00109 int lll, nnn;
00110 int nrhs, ierr;
00111 int i, j, jj, k, nn, itnum;
00112 int status;
00113
00114 int npt = 4000, nmd = 3100, nx0 = 100;
00115
00116 fprintf (stderr, "begin ola_xy()\n");
00117 aa1x = (double *)realloc (aa1x, nmd * nmd * sizeof (double));
00118 aa1y = (double *)realloc (aa1y, nmd * nmd * sizeof (double));
00119 avccx = (double *)realloc (avccx, nx0 * npt * sizeof (double));
00120 avccy = (double *)realloc (avccy, nx0 * npt * sizeof (double));
00121 avcx = (double *)realloc (avcx, npt * sizeof (double));
00122 avcy = (double *)realloc (avcy, npt * sizeof (double));
00123 cencx = (double *)realloc (cencx, nx0 * sizeof (double));
00124 cency = (double *)realloc (cency, nx0 * sizeof (double));
00125 ckintx = (double *)realloc (ckintx, nx0 * sizeof (double));
00126 ckinty = (double *)realloc (ckinty, nx0 * sizeof (double));
00127 rad = (double *)realloc (rad, npt * sizeof (double));
00128 fakc = (double *)realloc (fakc, npt * nmd * sizeof (double));
00129 rl = (double *)realloc (rl, nmd * sizeof (double));
00130 om = (double *)realloc (om, nmd * sizeof (double));
00131 dom = (double *)realloc (dom, 2 * nmd * sizeof (double));
00132 error = (double *)realloc (error, 2 * nmd * sizeof (double));
00133 weight = (double *)realloc (weight, npt * sizeof (double));
00134 n = (int *)realloc (n, nmd * sizeof (int));
00135 ipiv = (int *)realloc (ipiv, nmd * sizeof (int));
00136
00137 if (num > nx0) return 1;
00138 if (verbose) {
00139 printf ("frequency limits: %.3f - %.3f mHz\n", ob, oe);
00140 printf ("error trade-off parameter = %.5f\n", amu);
00141 }
00142 lun21 = fopen (filek1, "r");
00143 if (!lun21) {
00144 fprintf (stderr, "Error: unable to open input file %s\n", filek1);
00145 return 1;
00146 }
00147
00148 if (qave) {
00149
00150 char *filkern = (char *)malloc (sizeof (char) * (strlen (filker) + 3));
00151 sprintf (filkern, "Ux_%s", filker);
00152 lun19 = fopen (filkern, "w");
00153 if (!lun19) {
00154 fprintf (stderr, "Error: unable to open kernel output file %s\n", filkern);
00155 fclose (lun21);
00156 return 1;
00157 }
00158 sprintf (filkern, "Uy_%s", filker);
00159 lun29 = fopen (filkern, "w");
00160 if (!lun29) {
00161 fprintf (stderr, "Error: unable to open kernel output file %s\n", filkern);
00162 fclose (lun21);
00163 fclose (lun19);
00164 return 1;
00165 }
00166 free (filkern);
00167 }
00168 if (qcoef) {
00169
00170 char *filkern = (char *)malloc (sizeof (char) * (strlen (filcoef) + 3));
00171 sprintf (filkern, "Ux_%s", filcoef);
00172 lun27 = fopen (filkern, "w");
00173 if (!lun27) {
00174 fprintf (stderr, "Error: unable to open coefficient output file %s\n",
00175 filkern);
00176 fclose (lun21);
00177 if (qave) {
00178 fclose (lun19);
00179 fclose (lun29);
00180 }
00181 return 1;
00182 }
00183 sprintf (filkern, "Uy_%s", filcoef);
00184 lun37 = fopen (filkern, "w");
00185 if (!lun37) {
00186 fprintf (stderr, "Error: unable to open coefficient output file %s\n",
00187 filkern);
00188 fclose (lun37);
00189 fclose (lun21);
00190 if (qave) {
00191 fclose (lun19);
00192 fclose (lun29);
00193 }
00194 return 1;
00195 }
00196 free (filkern);
00197 }
00198
00199 bzero (fdif, sizeof (fdif));
00200 bzero (freq, sizeof (freq));
00201 bzero (err, sizeof (err));
00202
00203 ov1 = (double *)calloc (nmd * nmd, sizeof (double));
00204 cov = (double *)calloc (2 * nmd * nmd, sizeof (double));
00205 suml = (double *)calloc (3 * nmd * nmd, sizeof (double));
00206
00207 vv1x = (double *)calloc (num * nmd, sizeof (double));
00208 vv1y = (double *)calloc (num * nmd, sizeof (double));
00209 ctil1x = (double *)calloc (nmd * nx0, sizeof (double));
00210 ctil1y = (double *)calloc (nmd * nx0, sizeof (double));
00211 ctil2x = (double *)calloc (nmd * nx0, sizeof (double));
00212 ctil2y = (double *)calloc (nmd * nx0, sizeof (double));
00213
00214 nsp = 0;
00215 for (i = 0; i < nmodes; i++) {
00216 int ni = n_inp[i];
00217 int l = dl_inp[i];
00218 double f = 0.001 * f_inp[i];
00219 if (f > ob && f < oe) {
00220 freq[l][ni][0] = ux_inp[i];
00221 freq[l][ni][1] = uy_inp[i];
00222 err[l][ni][0] = euxinp[i];
00223 err[l][ni][1] = euyinp[i];
00224 fdif[l][ni] = f_inp[i];
00225 nsp++;
00226 }
00227 }
00228
00229 if (verbose) {
00230 printf ("nsp = %d\n", nsp);
00231 printf ("%d frequencies and velocities\n", i);
00232 printf ("MESSAGE: READ IN DATA\n");
00233 }
00234 fprintf (stderr, "ola_xy(): reading kernel\n");
00235
00236
00237 fscanf (lun21, "%g %g", &rs, &rms);
00238
00239 fscanf (lun21, "%d", &np);
00240 fprintf (stderr, "ola_xy(): np = %d, npt = %d\n", np, npt);
00241 rd = (float *)realloc (rd, np * sizeof (float));
00242 for (i = 0; i < np; i++) fscanf (lun21, "%g", &(rd[i]));
00243 ak = (float *)malloc (np * sizeof (float));
00244 if (verbose) printf ("R = %.7e, M = %.3e\n", rs, rms);
00245 nmode = 0;
00246 for (i = 0; i < 20000; i++) {
00247 if (fscanf (lun21, "%d %d %lg", &lll, &nnn, &ooo) != 3) break;
00248 for (nn = 0; nn < np; nn++) fscanf (lun21, "%g", &(ak[nn]));
00249 if (lll >= 2000) continue;
00250 if (nnn >= 50) continue;
00251 dif1 = freq[lll][nnn][0];
00252 dif2 = freq[lll][nnn][1];
00253 erri1 = err[lll][nnn][0];
00254 erri2 = err[lll][nnn][1];
00255 if (erri1 <= 1.0e-11) continue;
00256 if (erri2 <= 1.0e-11) continue;
00257 ot = fdif[lll][nnn];
00258
00259
00260
00261
00262
00263
00264 for (jj = 0; jj < np - 1; jj++) {
00265 fakc[npt*nmode + jj] = ak[jj];
00266 rad[jj] = rd[jj];
00267 }
00268 n[nmode] = nnn;
00269 rl[nmode] = lll;
00270 om[nmode] = 0.001 * ot;
00271 error[2*nmode] = erri1;
00272 error[2*nmode + 1] = erri2;
00273 dom[2*nmode] = dif1;
00274 dom[2*nmode + 1] = dif2;
00275 nmode++;
00276 }
00277 free (ak);
00278
00279
00280 if (verbose) printf ("np = %d\n", np);
00281 sume1 = sume2 = 0.0;
00282 for (i = 0; i < nmode; i++) {
00283 sume1 += 1.0 / (error[2*i] * error[2*i]);
00284 sume2 += 1.0 / (error[2*i + 1] * error[2*i + 1]);
00285 }
00286 if (verbose) printf ("read kernels %d\n", nmode);
00287
00288 fprintf (stderr, "ola_xy(): setting covariance matrix\n");
00289 sumcx = sumcy = 0.0;
00290 for (j = 0; j < nmode; j++) {
00291 sumcx += error[2*j] * error[2*j];
00292 cov[2*nmd*j + 2*j + 0] = error[2*j] * error[2*j];
00293 sumcy += error[2*j + 1] * error[2*j + 1];
00294 cov[2*nmd*j + 2*j + 1] = error[2*j + 1] * error[2*j + 1];
00295 }
00296 sumcx /= nmode;
00297 sumcy /= nmode;
00298 if (verbose) {
00299 printf ("sumc: %g, %g\n", sumcx, sumcy);
00300 printf ("calc. integration weights\n");
00301 }
00302
00303 fprintf (stderr, "ola_xy(): calculating integration weights\n");
00304 fprintf (stderr, "ola_xy(): np = %d, npt = %d\n", np, npt);
00305 weight[0] = 0.5 * (rad[0] - rad[1]);
00306 for (j = 0; j < np - 2; j++) weight[j+1] = 0.5 * (rad[j] - rad[j+2]);
00307 weight[np-1] = 0.5 * (rad[np-2] - rad[np-1]);
00308
00309 fprintf (stderr, "ola_xy(): calculating overlap matrix\n");
00310 if (verbose) printf ("calc overlap matrix\n");
00311
00312 for (i = 0; i < nmode; i++) {
00313 for (j = 0; j < nmode; j++) {
00314 sum2 = sum3 = sa = sb = sc = 0.0;
00315 for (k = 0; k < np; k++) {
00316 term = weight[k] * fakc[npt*i + k] * fakc[npt*j + k];
00317 sa += term * rad[k] * rad[k];
00318 sb += term * rad[k];
00319 sc += term;
00320 }
00321 suml[nmd*nmd*0 + nmd*j + i] = suml[nmd*nmd*0 + nmd*i + j] = sa;
00322 suml[nmd*nmd*1 + nmd*j + i] = suml[nmd*nmd*1 + nmd*i + j] = sb;
00323 suml[nmd*nmd*2 + nmd*j + i] = suml[nmd*nmd*2 + nmd*i + j] = sc;
00324 }
00325 }
00326
00327 for (i = 0; i < nmode; i++) {
00328 sum1 = 0.0;
00329 for (k = 0; k < np; k++) sum1 += weight[k] * fakc[k + npt*i];
00330 ov1[i + nmode*nmd] = ov1[nmode + i*nmd] = 0.5 * sum1;
00331 suml[i + nmode*nmd] = suml[nmode + i*nmd] = 0.5 * sum1;
00332 }
00333
00334 numker = nmode + 1;
00335 if (verbose) printf ("numker = %d\n", numker);
00336
00337 if (verbose) printf ("calc. targets\n");
00338 ntab = np;
00339 dx = (endd - beg) / (num - 1.0);
00340 for (i = 0; i < num; i++) x0[i] = beg + i * dx;
00341
00342 for (itnum = 0; itnum < num; itnum++) {
00343
00344 if (verbose) printf ("calc. ov1\n");
00345 for (i = 0; i < nmode; i++) {
00346 for (j = i; j < nmode; j++) {
00347 sum1 = suml[nmd*nmd*0 + nmd*j + i] -
00348 2 * x0[itnum] * suml[nmd*nmd*1 + nmd*j + i] +
00349 x0[itnum] * x0[itnum] * suml[nmd*nmd*2 + nmd*j + i];
00350 ov1[i + j*nmd] = ov1[j + i*nmd] = sum1;
00351 }
00352 }
00353
00354 for (j = 0; j < num; j++)
00355 vv1x[nmode + j*nmd] = vv1y[nmode + j*nmd] = 0.5;
00356
00357 if (verbose) printf ("calc. lhs\n");
00358 for (j = 0; j < nmode; j++) {
00359 for (i = 0; i < nmode; i++) {
00360 cc = cov[j*2*nmd + i*2 + 0] / sumcx;
00361 aa1x[i + j*nmd] = ov1[i + j*nmd] + amu * cc;
00362 cc = cov[j*2*nmd + i*2 + 1] / sumcy;
00363 aa1y[i + j*nmd] = ov1[i + j*nmd] + amu * cc;
00364 }
00365 }
00366 if (verbose) printf ("numker = %d %d\n", numker, nmode);
00367 for (j = 0; j < numker; j++) {
00368 for (i = nmode; i < numker; i++) {
00369 aa1x[i + j*nmd] = aa1y[i + j*nmd] = ov1[i + j*nmd];
00370 aa1x[j + i*nmd] = aa1y[j + i*nmd] = ov1[j + i*nmd];
00371 }
00372 for (k = 0; k < num; k++) {
00373 ctil1x[j + k*nmd] = vv1x[j + k*nmd];
00374 ctil1y[j + k*nmd] = vv1y[j + k*nmd];
00375 }
00376 }
00377
00378
00379
00380
00381
00382
00383
00384
00385 status = solve (nmd, nmd, numker, 1, aa1x, ctil1x);
00386
00387 if (verbose) printf ("done Ux\n");
00388
00389
00390
00391
00392
00393
00394
00395 status = solve (nmd, nmd, numker, 1, aa1y, ctil1y);
00396
00397 if (verbose) printf ("done Uy\n");
00398 jj = 0;
00399 for (i = 0; i < numker; i++) {
00400 ctil2x[i + itnum*nmd] = ctil1x[i + jj*nmd];
00401 ctil2y[i + itnum*nmd] = ctil1y[i + jj*nmd];
00402 }
00403
00404 for (j = 0; j < np; j++) {
00405 sumccx = sumccy = 0.0;
00406 for (i = 0; i < nmode; i++) {
00407 sumccx += ctil1x[i + jj*nmd] * fakc[j + i*npt];
00408 sumccy += ctil1y[i + jj*nmd] * fakc[j + i*npt];
00409 }
00410 avcx[j] = sumccx;
00411 avccx[nx0*j + itnum] = sumccx;
00412 avcy[j] = sumccy;
00413 avccy[nx0*j + itnum] = sumccy;
00414 }
00415
00416 sumc1x = sumc2x = sumc1y = sumc2y = 0.0;
00417 for (j = 0; j < np; j++) {
00418 sumc1x += weight[j] * rad[j] * avcx[j];
00419 sumc2x += weight[j] * avcx[j];
00420 sumc1y += weight[j] * rad[j] * avcy[j];
00421 sumc2y += weight[j] * avcy[j];
00422 }
00423 if (verbose) printf ("int. %g\n", sumc1x);
00424 cencx[0] = sumc1x / sumc2x;
00425 ckintx[0] = sumc2x;
00426 cency[0] = sumc1y / sumc2y;
00427 ckinty[0] = sumc2y;
00428 if (verbose) printf ("calling width for Ux\n");
00429 fwidth_ (&npt, &np, &num, rad, avcx, dthcx, &verbose);
00430 if (verbose) printf ("width done for Ux: %g %g %g\n",
00431 dthcx[0], dthcx[1], dthcx[2]);
00432 if (verbose) printf ("calling width for Uy\n");
00433 fwidth_ (&npt, &np, &num, rad, avcy, dthcy, &verbose);
00434 if (verbose) printf ("width done for Uy: %g %g %g\n",
00435 dthcy[0], dthcy[1], dthcy[2]);
00436
00437 sum1x = er1x = sum1y = er1y = 0.0;
00438
00439 for (i = 0; i < nmode; i++) {
00440
00441 sum1x += ctil1x[i] * dom[2*i];
00442 er1x += ctil1x[i] * ctil1x[i] * cov[2*nmd*i + 2*i];
00443 sum1y += ctil1y[i] * dom[2*i + 1];
00444 er1y += ctil1y[i] * ctil1y[i] * cov[2*nmd*i + 2*i + 1];
00445
00446 }
00447
00448
00449
00450
00451
00452
00453
00454
00455 s1x = fabs (dthcx[0] - dthcx[2]);
00456 s1y = fabs (dthcy[0] - dthcy[2]);
00457 er1x = sqrt (er1x);
00458 er1y = sqrt (er1y);
00459 if (verbose) printf ("%g %g %g\n", x0[itnum], sum1x, er1x);
00460 rcgx[itnum] = cencx[0];
00461 rcgy[itnum] = cency[0];
00462 for (i = 0; i < 3; i++) {
00463 quartx[i + 3*itnum] = dthcx[i];
00464 quarty[i + 3*itnum] = dthcy[i];
00465 }
00466 solnx[itnum] = sum1x;
00467 solny[itnum] = sum1y;
00468 errx[itnum] = er1x;
00469 erry[itnum] = er1y;
00470
00471
00472
00473
00474
00475
00476
00477
00478 }
00479
00480 if (qave) {
00481
00482 fprintf (lun19, "# radius ");
00483 fprintf (lun29, "# radius ");
00484 for (i = 0; i < num; i++) fprintf (lun19, "%13.5e", x0[i]);
00485 for (i = 0; i < num; i++) fprintf (lun29, "%13.5e", x0[i]);
00486 for (j = 0; j < np; j += 2) {
00487 fprintf (lun19, "%14.6e", rad[j]);
00488 for (k = 0; k < num; k++) fprintf (lun19, "%14.6e", avccx[nx0*j + k]);
00489 fprintf (lun29, "%14.6e", rad[j]);
00490 for (k = 0; k < num; k++) fprintf (lun29, "%14.6e", avccy[nx0*j + k]);
00491 }
00492 fclose (lun19);
00493 fclose (lun29);
00494 }
00495 if (qcoef) {
00496
00497 fprintf (lun27, "# ");
00498 for (i = 0; i < num; i++) fprintf (lun27, "%13.5e", x0[i]);
00499 fprintf (lun27, "\n");
00500 fprintf (lun37, "# ");
00501 for (i = 0; i < num; i++) fprintf (lun37, "%13.5e", x0[i]);
00502 fprintf (lun37, "\n");
00503 for (j = 0; j < numker - 1; j++) {
00504 for (i = 0; i < num; i++) fprintf (lun27, "%14.6e", ctil2x[i + j * nmd]);
00505 fprintf (lun27, "\n");
00506 for (i = 0; i < num; i++) fprintf (lun37, "%14.6e", ctil2y[i + j * nmd]);
00507 fprintf (lun37, "\n");
00508 }
00509 fclose (lun27);
00510 fclose (lun37);
00511 }
00512 fclose (lun21);
00513
00514 free (ov1);
00515 free (cov);
00516 free (suml);
00517 free (vv1x);
00518 free (vv1y);
00519 free (ctil1x);
00520 free (ctil1y);
00521 free (ctil2x);
00522 free (ctil2y);
00523
00524 return 0;
00525 }