- Timestamp:
- Oct 11, 2021, 11:17:06 AM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-dev-20210817/Ohana/src/opihi/cmd.data/fit2d.c
r39020 r41830 294 294 return (TRUE); 295 295 } 296 297 int fit2d_full (int argc, char **argv) { 298 299 int N; 300 char name[64]; 301 302 int VERBOSE = FALSE; 303 if ((N = get_argument (argc, argv, "-v"))) { 304 VERBOSE = TRUE; 305 remove_argument (N, &argc, argv); 306 } 307 308 int Quiet = FALSE; 309 if ((N = get_argument (argc, argv, "-q"))) { 310 Quiet = TRUE; 311 remove_argument (N, &argc, argv); 312 } 313 if ((N = get_argument (argc, argv, "-quiet"))) { 314 Quiet = TRUE; 315 remove_argument (N, &argc, argv); 316 } 317 318 float ClipNSigma = 0; 319 int ClipNiter = 1; 320 if ((N = get_argument (argc, argv, "-clip"))) { 321 remove_argument (N, &argc, argv); 322 ClipNSigma = atof(argv[N]); 323 remove_argument (N, &argc, argv); 324 ClipNiter = atof(argv[N]); 325 remove_argument (N, &argc, argv); 326 } 327 328 opihi_flt *dz = NULL; 329 Vector *dzvec = NULL; 330 int Weight = FALSE; 331 if ((N = get_argument (argc, argv, "-dz"))) { 332 remove_argument (N, &argc, argv); 333 if ((dzvec = SelectVector (argv[N], OLDVECTOR, TRUE)) == NULL) return (FALSE); 334 remove_argument (N, &argc, argv); 335 Weight = TRUE; 336 } 337 338 if (argc != 5) { 339 gprint (GP_ERR, "USAGE: fit2d_full x y z order [-dz wt] [-quiet/-q] [-clip Nsigma Niter]\n"); 340 return (FALSE); 341 } 342 343 Vector *xvec, *yvec, *zvec; 344 if ((xvec = SelectVector (argv[1], OLDVECTOR, TRUE)) == NULL) return (FALSE); 345 if ((yvec = SelectVector (argv[2], OLDVECTOR, TRUE)) == NULL) return (FALSE); 346 if ((zvec = SelectVector (argv[3], OLDVECTOR, TRUE)) == NULL) return (FALSE); 347 348 if (xvec[0].Nelements != yvec[0].Nelements) { 349 gprint (GP_ERR, "vectors must have same length\n"); 350 return (FALSE); 351 } 352 if (xvec[0].Nelements != zvec[0].Nelements) { 353 gprint (GP_ERR, "vectors must have same length\n"); 354 return (FALSE); 355 } 356 CastVector (xvec, OPIHI_FLT); 357 CastVector (yvec, OPIHI_FLT); 358 CastVector (zvec, OPIHI_FLT); 359 360 if (Weight) { 361 CastVector (dzvec, OPIHI_FLT); 362 if (xvec[0].Nelements != dzvec[0].Nelements) { 363 gprint (GP_ERR, "vectors must have same length\n"); 364 return (FALSE); 365 } 366 } 367 368 int order = atof (argv[4]); 369 int nterm = SQ(order + 1); 370 371 ALLOCATE_PTR (zfit, opihi_flt, xvec[0].Nelements); 372 ALLOCATE_PTR (mask, char, xvec[0].Nelements); 373 memset (mask, 0, xvec[0].Nelements); 374 375 /* allocate the summation matrices */ 376 ALLOCATE_PTR (b, double *, nterm); 377 ALLOCATE_PTR (c, double *, nterm); 378 for (int i = 0; i < nterm; i++) { 379 ALLOCATE (c[i], double, nterm); 380 ALLOCATE (b[i], double, 1); 381 } 382 383 for (N = 0; N < ClipNiter; N++) { 384 385 /* init registers for current pass */ 386 for (int i = 0; i < nterm; i++) { 387 memset (c[i], 0, nterm*sizeof(double)); 388 memset (b[i], 0, sizeof(double)); 389 } 390 391 opihi_flt *x = xvec[0].elements.Flt; 392 opihi_flt *y = yvec[0].elements.Flt; 393 opihi_flt *z = zvec[0].elements.Flt; 394 if (Weight) dz = dzvec[0].elements.Flt; 395 396 /* add up the x,y values */ 397 for (int i = 0; i < xvec[0].Nelements; i++, x++, y++, z++) { 398 if (mask[i]) continue; 399 if (!finite(*x) || !finite(*y)) continue; 400 double dZ = 1.0; 401 if (Weight) { 402 dZ = 1.0 / SQ(*dz); 403 dz ++; 404 } 405 406 int n = 0; 407 double iY = 1*dZ; 408 double iX = iY; 409 410 for (int iy = 0; iy <= order; iy++) { 411 iX = iY; 412 for (int ix = 0; ix <= order; ix++) { 413 b[n][0] += iX * (*z); 414 415 int m = 0; 416 double jY = 1; 417 double jX = jY; 418 419 for (int jy = 0; jy <= order; jy++) { 420 jX = jY; 421 for (int jx = 0; jx <= order; jx++) { 422 c[n][m] += iX*jX; 423 jX = jX * (*x); 424 m ++; 425 } 426 jY = jY * (*y); 427 } 428 iX = iX * (*x); 429 n ++; 430 } 431 iY = iY * (*y); 432 } 433 } 434 435 /** test print **/ 436 if (VERBOSE) { 437 for (int i = 0; i < nterm; i++) { 438 for (int j = 0; j < nterm; j++) { 439 gprint (GP_ERR, "%g ", c[i][j]); 440 } 441 gprint (GP_ERR, "\n"); 442 } 443 gprint (GP_ERR, "-----\n"); 444 } 445 446 dgaussjordan (c, b, nterm, 1); 447 448 /** test print **/ 449 if (VERBOSE) { 450 int n = 0; 451 for (int ny = 0; ny <= order; ny++) { 452 for (int nx = 0; nx <= order; nx++) { 453 gprint (GP_ERR, "x^%d y^%d: %g\n", nx, ny, b[n][0]); 454 n ++; 455 } 456 } 457 } 458 459 /** test print **/ 460 if (VERBOSE) { 461 for (int i = 0; i < nterm; i++) { 462 for (int j = 0; j < nterm; j++) { 463 gprint (GP_ERR, "%g ", c[i][j]); 464 } 465 gprint (GP_ERR, "\n"); 466 } 467 gprint (GP_ERR, "-----\n"); 468 } 469 470 /* the b[][0] terms are in the following order: 471 y^0 x^0, y^0 x^1, ... y^0 x^N 472 y^1 x^0, y^1 x^1, ... y^1 x^N 473 ... 474 y^N x^0, y^N x^1, ... y^N x^N 475 */ 476 477 /* generate fitted values */ 478 x = xvec[0].elements.Flt; 479 y = yvec[0].elements.Flt; 480 opihi_flt *zf = zfit; 481 for (int n = 0; n < xvec[0].Nelements; n++, x++, y++, zf++) { 482 if (!finite(*x) || !finite(*y)) continue; 483 *zf = 0; 484 double Y = 1; 485 double X = Y; 486 487 int n = 0; 488 for (int ny = 0; ny <= order; ny++) { 489 X = Y; 490 for (int nx = 0; nx <= order; nx++) { 491 *zf += b[n][0]*X; 492 X = X * (*x); 493 n ++; 494 } 495 Y = Y * (*y); 496 } 497 } 498 499 /* measure fit residual scatter */ 500 x = xvec[0].elements.Flt; 501 y = yvec[0].elements.Flt; 502 z = zvec[0].elements.Flt; 503 zf = zfit; 504 double dZ = 0.0; 505 double dZ2 = 0.0; 506 int Npt = 0; 507 for (int i = 0, Npt = 0; i < xvec[0].Nelements; i++, x++, y++, z++, zf++) { 508 if (mask[i]) continue; 509 if (!finite(*x) || !finite(*y)) continue; 510 dZ += (*z - *zf); 511 dZ2 += SQ(*z - *zf); 512 Npt ++; 513 } 514 double mean = dZ / Npt; 515 double sigma = sqrt (fabs(dZ2/Npt - SQ(mean))); 516 double maxsigma = ClipNSigma * sigma; 517 518 if (VERBOSE) gprint (GP_ERR, "mean: %g, sigma: %g, maxsigma: %g\n", mean, sigma, maxsigma); 519 520 /* mask outlier points */ 521 x = xvec[0].elements.Flt; 522 y = yvec[0].elements.Flt; 523 z = zvec[0].elements.Flt; 524 zf = zfit; 525 int Nmask = 0; 526 for (int i = 0; ClipNSigma && (i < xvec[0].Nelements); i++, x++, y++, z++, zf++) { 527 dZ = (*z - *zf); 528 if (fabs(dZ) > maxsigma) { 529 mask[i] = TRUE; 530 Nmask ++; 531 } else { 532 mask[i] = FALSE; 533 } 534 } 535 if (VERBOSE) gprint (GP_ERR, "pass: %d, Nmask: %d\n", N, Nmask); 536 } 537 538 if (!Quiet) gprint (GP_ERR, "z = "); 539 int n = 0; 540 for (int ny = 0; ny <= order; ny++) { 541 for (int nx = 0; nx <= order; nx++) { 542 sprintf (name, "CX%dY%d", nx, ny); 543 set_variable (name, b[n][0]); 544 if (!Quiet) gprint (GP_ERR, "%f x^%d y^%d ", b[n][0], nx, ny); 545 n++; 546 } 547 } 548 sprintf (name, "Cnn"); 549 set_variable (name, (double) order); 550 551 if (!Quiet) gprint (GP_ERR, "\n"); 552 553 /* free internal data */ 554 free (zfit); 555 free (mask); 556 557 for (int i = 0; i < nterm; i++) { 558 free (c[i]); 559 free (b[i]); 560 } 561 free (b); 562 free (c); 563 564 return (TRUE); 565 }
Note:
See TracChangeset
for help on using the changeset viewer.
