IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 3687


Ignore:
Timestamp:
Apr 8, 2005, 10:06:52 AM (21 years ago)
Author:
eugene
Message:

added robust fitting

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Ohana/src/opihi/cmd.data/fit.c

    r3104 r3687  
    33int fit (int argc, char **argv) {
    44 
    5   double **c, **b, *s, X, Y, dY;
    6   int i, j, nterm, mterm, order;
    7   int N, Weight, Quiet;
     5  double **c, **b, *s, X, Y, dY, dY2;
     6  double ClipNSigma, mean, sigma, maxsigma;
     7  int i, j, nterm, mterm, order, Npt, Nmask;
     8  int N, Weight, Quiet, ClipNiter;
    89  Vector *xvec, *yvec, *dyvec;
    9   float *x, *y, *dy;
    10   char name[64];
     10  float *x, *y, *dy, *yf, *yfit;
     11  char name[64], *mask;
    1112
    1213  Quiet = FALSE;
     
    2021  }
    2122
     23  ClipNSigma = 0;
     24  ClipNiter  = 1;
     25  if ((N = get_argument (argc, argv, "-clip"))) {
     26    remove_argument (N, &argc, argv);
     27    ClipNSigma = atof(argv[N]);
     28    remove_argument (N, &argc, argv);
     29    ClipNiter  = atof(argv[N]);
     30    remove_argument (N, &argc, argv);
     31  }
     32
    2233  Weight = FALSE;
    2334  if ((N = get_argument (argc, argv, "-dy"))) {
     
    2940
    3041  if (argc != 4) {
    31     fprintf (stderr, "USAGE: fit x y order [-dy wt]\n");
     42    fprintf (stderr, "USAGE: fit x y order [-dy wt] [-quiet/-q] [-clip Nsigma Niter]\n");
    3243    return (FALSE);
    3344  }
     
    3647  if ((yvec = SelectVector (argv[2], OLDVECTOR, TRUE)) == NULL) return (FALSE);   
    3748
     49  if (xvec[0].Nelements != yvec[0].Nelements) {
     50    fprintf (stderr, "vectors must have same length\n");
     51    return (FALSE);
     52  }
     53  if (Weight && xvec[0].Nelements != dyvec[0].Nelements) {
     54    fprintf (stderr, "vectors must have same length\n");
     55    return (FALSE);
     56  }
     57 
    3858  order = atof (argv[3]);
    3959  nterm = order + 1;
    4060  mterm = 2*order + 1;
    4161
    42   if (xvec[0].Nelements != yvec[0].Nelements) {
    43     fprintf (stderr, "vectors must have same length\n");
    44     return (FALSE);
    45   }
    46   if (Weight && xvec[0].Nelements != dyvec[0].Nelements) {
    47     fprintf (stderr, "vectors must have same length\n");
    48     return (FALSE);
    49   }
    50  
    51   x = xvec[0].elements;
    52   y = yvec[0].elements;
    53   if (Weight) dy = dyvec[0].elements;
     62  ALLOCATE (yfit, float, xvec[0].Nelements);
     63  ALLOCATE (mask, char, xvec[0].Nelements);
     64  memset (mask, 0, xvec[0].Nelements);
    5465
    5566  ALLOCATE (s, double, 2*mterm);
    56   bzero (s, 2*mterm*sizeof(double));
    5767  ALLOCATE (b, double *, nterm);
    5868  ALLOCATE (c, double *, nterm);
    5969  for (i = 0; i < nterm; i++) {
    6070    ALLOCATE (c[i], double, nterm);
    61     bzero (c[i], nterm*sizeof(double));
    6271    ALLOCATE (b[i], double, 1);
    63     bzero (b[i], sizeof(double));
    64   }
    65 
    66   for (i = 0; i < xvec[0].Nelements; i++, x++, y++) {
    67     if (!(finite(*x) && finite(*y))) continue;
    68     dY = 1.0;
    69     if (Weight) {
    70       dY = 1.0 / SQ(*dy);
    71       dy ++;
    72     }
    73     X = 1*dY;
    74     Y = *y*dY;
    75     for (j = 0; j < nterm; j++) {
    76       s[j] += X;
    77       b[j][0] += Y;
    78       X = X * (*x);
    79       Y = Y * (*x);
    80     }
    81     for (j = nterm; j < mterm; j++) {
    82       s[j] += X;
    83       X = X * (*x);
    84     }
    85   }
    86 
    87   for (i = 0; i < nterm; i++) {
    88     for (j = 0; j < nterm; j++) {
    89       c[i][j] = s[i + j];
    90     }
    91   }
    92   if (!gaussj (c, nterm, b, 1)) goto escape;
    93 
     72  }
     73
     74  for (N = 0; N < ClipNiter; N++) {
     75
     76    /* init registers for current pass */
     77    memset (s, 0, 2*mterm*sizeof(double));
     78    for (i = 0; i < nterm; i++) {
     79      memset (c[i], 0, nterm*sizeof(double));
     80      memset (b[i], 0, sizeof(double));
     81    }
     82
     83    /* perform linear fit */
     84    x = xvec[0].elements;
     85    y = yvec[0].elements;
     86    if (Weight) dy = dyvec[0].elements;
     87    for (i = 0; i < xvec[0].Nelements; i++, x++, y++) {
     88      if (mask[i]) continue;
     89      if (!(finite(*x) && finite(*y))) continue;
     90      dY = 1.0;
     91      if (Weight) {
     92        dY = 1.0 / SQ(*dy);
     93        dy ++;
     94      }
     95      X = 1*dY;
     96      Y = *y*dY;
     97      for (j = 0; j < nterm; j++) {
     98        s[j] += X;
     99        b[j][0] += Y;
     100        X = X * (*x);
     101        Y = Y * (*x);
     102      }
     103      for (j = nterm; j < mterm; j++) {
     104        s[j] += X;
     105        X = X * (*x);
     106      }
     107    }
     108    for (i = 0; i < nterm; i++) {
     109      for (j = 0; j < nterm; j++) {
     110        c[i][j] = s[i + j];
     111      }
     112    }
     113    if (!gaussj (c, nterm, b, 1)) goto escape;
     114
     115    /* generate fitted values */
     116    x = xvec[0].elements;
     117    yf = yfit;
     118    for (i = 0; i < xvec[0].Nelements; i++, x++, yf++) {
     119      if (!finite(*x)) continue;
     120      *yf = 0;
     121      X = 1;
     122      for (j = 0; j < order + 1; j++) {
     123        *yf += b[j][0]*X;
     124        X = X * (*x);
     125      }
     126    }
     127
     128    /* measure fit residual scatter */
     129    x  = xvec[0].elements;
     130    y  = yvec[0].elements;
     131    yf = yfit;
     132    dY = dY2 = 0;
     133    for (i = Npt = 0; i < xvec[0].Nelements; i++, x++, y++, yf++) {
     134      if (mask[i]) continue;
     135      if (!finite(*x)) continue;
     136      dY  += (*y - *yf);
     137      dY2 += SQ(*y - *yf);
     138      Npt ++;
     139    }
     140    mean  = dY / Npt;
     141    sigma = sqrt (fabs(dY2/Npt - SQ(mean)));
     142    maxsigma = ClipNSigma * sigma;
     143
     144    /* mask outlier points */
     145    x  = xvec[0].elements;
     146    y  = yvec[0].elements;
     147    yf = yfit;
     148    Nmask = 0;
     149    for (i = 0; ClipNSigma && (i < xvec[0].Nelements); i++, x++, y++, yf++) {
     150      dY = (*y - *yf);
     151      if (fabs(dY) > maxsigma) {
     152        mask[i] = TRUE;
     153        Nmask ++;
     154      } else {
     155        mask[i] = FALSE;
     156      }
     157    }
     158  }
     159     
    94160  /* print & save basic fit parameters */
    95161  if (!Quiet) fprintf (stderr, "y = ");
     
    112178  if (!Quiet) fprintf (stderr, "\n");
    113179
     180  set_variable ("dC", sigma);
     181  set_variable ("Cnv", (xvec[0].Nelements - Nmask));
     182
     183  /* save mask and yfit for testing? */
     184  if (1) {
     185    Vector *fvec, *mvec;
     186    if ((fvec = SelectVector ("yfit", ANYVECTOR, TRUE)) == NULL) return (FALSE);   
     187    if ((mvec = SelectVector ("mask", ANYVECTOR, TRUE)) == NULL) return (FALSE);   
     188    free (fvec[0].elements);
     189    fvec[0].elements = yfit;
     190    fvec[0].Nelements = xvec[0].Nelements;
     191    mvec[0].Nelements = xvec[0].Nelements;
     192
     193    REALLOCATE (mvec[0].elements, float, xvec[0].Nelements);
     194    for (i = 0; i < xvec[0].Nelements; i++) {
     195      mvec[0].elements[i] = mask[i];
     196    }
     197  } else {
     198    free (yfit);
     199  }
     200  free (mask);
     201
    114202  for (i = 0; i < nterm; i++) {
    115203    free (b[i]);
Note: See TracChangeset for help on using the changeset viewer.