IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
May 11, 2005, 9:39:34 PM (21 years ago)
Author:
eugene
Message:

added robust fitting

File:
1 edited

Legend:

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

    r2843 r3897  
    33int fit2d (int argc, char **argv) {
    44 
    5   double **c, **b, **s, X, Y;
    6   int k, K, i, j, nx, ny, nterm, mterm, wterm, order;
    7   int N, Weight;
    8   float *x, *y, *z;
    9   char name[64];
    10   Vector *xvec, *yvec, *zvec, *dyvec;
     5  double **c, **b, **s, X, Y, dZ, dZ2;
     6  double ClipNSigma, mean, sigma, maxsigma;
     7  int k, K, i, j, n, Npt, Nmask, nx, ny, nterm, mterm, wterm, order;
     8  int N, Weight, Quiet, ClipNiter, VERBOSE;
     9  float *x, *y, *z, *dz, *zfit, *zf;
     10  char name[64], *mask;
     11  Vector *xvec, *yvec, *zvec, *dzvec;
     12
     13  VERBOSE = FALSE;
     14  if ((N = get_argument (argc, argv, "-v"))) {
     15    VERBOSE = TRUE;
     16    remove_argument (N, &argc, argv);
     17  }
     18
     19  Quiet = FALSE;
     20  if ((N = get_argument (argc, argv, "-q"))) {
     21    Quiet = TRUE;
     22    remove_argument (N, &argc, argv);
     23  }
     24  if ((N = get_argument (argc, argv, "-quiet"))) {
     25    Quiet = TRUE;
     26    remove_argument (N, &argc, argv);
     27  }
     28
     29  ClipNSigma = 0;
     30  ClipNiter  = 1;
     31  if ((N = get_argument (argc, argv, "-clip"))) {
     32    remove_argument (N, &argc, argv);
     33    ClipNSigma = atof(argv[N]);
     34    remove_argument (N, &argc, argv);
     35    ClipNiter  = atof(argv[N]);
     36    remove_argument (N, &argc, argv);
     37  }
    1138
    1239  Weight = FALSE;
    13   if ((N = get_argument (argc, argv, "-dy"))) {
    14     remove_argument (N, &argc, argv);
    15     if ((dyvec = SelectVector (argv[N], OLDVECTOR, TRUE)) == NULL) return (FALSE);   
     40  if ((N = get_argument (argc, argv, "-dz"))) {
     41    remove_argument (N, &argc, argv);
     42    if ((dzvec = SelectVector (argv[N], OLDVECTOR, TRUE)) == NULL) return (FALSE);   
    1643    remove_argument (N, &argc, argv);
    1744    Weight = TRUE;
    18     fprintf (stderr, "warning: weighting currently ignored!\n");
    1945  }
    2046
    2147  if (argc != 5) {
    22     fprintf (stderr, "USAGE: fit x y z order [-dy`z wt]\n");
     48    fprintf (stderr, "USAGE: fit x y z order [-dz wt]\n");
    2349    return (FALSE);
    2450  }
     
    2854  if ((zvec = SelectVector (argv[3], OLDVECTOR, TRUE)) == NULL) return (FALSE);   
    2955
     56  if (xvec[0].Nelements != yvec[0].Nelements) {
     57    fprintf (stderr, "vectors must have same length\n");
     58    return (FALSE);
     59  }
     60  if (xvec[0].Nelements != zvec[0].Nelements) {
     61    fprintf (stderr, "vectors must have same length\n");
     62    return (FALSE);
     63  }
     64  if (Weight && xvec[0].Nelements != dzvec[0].Nelements) {
     65    fprintf (stderr, "vectors must have same length\n");
     66    return (FALSE);
     67  }
     68 
    3069  order = atof (argv[4]);
    3170  nterm = order + 1;
     
    3372  mterm = 2*order + 1;
    3473
    35   if (xvec[0].Nelements != yvec[0].Nelements) {
    36     fprintf (stderr, "vectors must have same length\n");
    37     return (FALSE);
    38   }
    39   if (xvec[0].Nelements != zvec[0].Nelements) {
    40     fprintf (stderr, "vectors must have same length\n");
    41     return (FALSE);
    42   }
    43   if (Weight && xvec[0].Nelements != dyvec[0].Nelements) {
    44     fprintf (stderr, "vectors must have same length\n");
    45     return (FALSE);
    46   }
    47  
    48   x = xvec[0].elements;
    49   y = yvec[0].elements;
    50   z = zvec[0].elements;
    51   /* dy = dyvec[0].elements; */
     74  ALLOCATE (zfit, float, xvec[0].Nelements);
     75  ALLOCATE (mask, char, xvec[0].Nelements);
     76  memset (mask, 0, xvec[0].Nelements);
    5277
    5378  /* allocate the summation matrices */
     79  ALLOCATE (s, double *, mterm);
    5480  ALLOCATE (b, double *, wterm);
    5581  ALLOCATE (c, double *, wterm);
    5682  for (i = 0; i < wterm; i++) {
    5783    ALLOCATE (c[i], double, wterm);
    58     bzero (c[i], wterm*sizeof(double));
    5984    ALLOCATE (b[i], double, 1);
    60     bzero (b[i], sizeof(double));
    61   }
    62   ALLOCATE (s, double *, mterm);
     85  }
    6386  for (i = 0; i < mterm; i++) {
    6487    ALLOCATE (s[i], double, mterm);
    65     bzero (s[i], mterm*sizeof(double));
    66   }
    67 
    68   /* add up the x,y values */
    69   for (i = 0; i < xvec[0].Nelements; i++, x++, y++) {
    70     Y = X = 1;
    71     for (ny = 0; ny < mterm; ny++) {
    72       X = Y;
    73       for (nx = 0; nx < mterm - ny; nx++) {
    74         s[nx][ny] += X;
     88  }
     89
     90  for (N = 0; N < ClipNiter; N++) {
     91
     92    /* init registers for current pass */
     93    for (i = 0; i < nterm; i++) {
     94      memset (c[i], 0, wterm*sizeof(double));
     95      memset (b[i], 0, sizeof(double));
     96    }
     97    for (i = 0; i < mterm; i++) {
     98      memset (s[i], 0, mterm*sizeof(double));
     99    }
     100
     101    x = xvec[0].elements;
     102    y = yvec[0].elements;
     103    z = zvec[0].elements;
     104    if (Weight) dz = dzvec[0].elements;
     105
     106    /* add up the x,y values */
     107    for (i = 0; i < xvec[0].Nelements; i++, x++, y++) {
     108      if (mask[i]) continue;
     109      if (!finite(*x) || !finite(*y)) continue;
     110      dZ = 1.0;
     111      if (Weight) {
     112        dZ = 1.0 / SQ(*dz);
     113        dz ++;
     114      }
     115      Y = X = 1*dZ;
     116      for (ny = 0; ny < mterm; ny++) {
     117        X = Y;
     118        for (nx = 0; nx < mterm - ny; nx++) {
     119          s[nx][ny] += X;
     120          X = X * (*x);
     121        }
     122        Y = Y * (*y);
     123      }
     124    }
     125
     126    /* add up the z values */
     127    x = xvec[0].elements;
     128    y = yvec[0].elements;
     129    z = zvec[0].elements;
     130    for (i = 0; i < xvec[0].Nelements; i++, x++, y++, z++) {
     131      if (mask[i]) continue;
     132      if (!finite(*x) || !finite(*y)) continue;
     133      dZ = 1.0;
     134      if (Weight) {
     135        dZ = 1.0 / SQ(*dz);
     136        dz ++;
     137      }
     138      Y = X = *z*dZ;
     139      for (j = 0, ny = 0; ny < nterm; ny++) {
     140        X = Y;
     141        for (nx = 0; nx < nterm - ny; nx++, j++) {
     142          b[j][0] += X;
     143          X = X * (*x);
     144        }
     145        Y = Y * (*y);
     146      }
     147    }
     148
     149    /* re-sort mterm x mterm matrix to wterm matrix */
     150    for (k = j = 0; j < nterm; j++) {
     151      for (i = 0; i < nterm - j; i++, k++) {
     152        for (K = ny = 0; ny < nterm; ny++) {
     153          for (nx = 0; nx < nterm - ny; nx++, K++) {
     154            c[K][k] = s[nx+i][ny+j];
     155          }
     156        }
     157      }
     158    }
     159
     160    gaussj (c, wterm, b, 1);
     161
     162    /** test print **/
     163    if (VERBOSE) {
     164      for (i = ny = 0; ny < nterm; ny++) {
     165        for (nx = 0; nx < nterm - ny; nx++, i++) {
     166          fprintf (stderr, "x^%d y^%d: %g\n", nx, ny, b[i][0]);
     167        }
     168      }
     169    }
     170
     171    /* the b[][0] terms are in the following order:
     172       y^0 x^0, y^0 x^1, ... y^0 x^N
     173       y^1 x^0, y^1 x^1, ... y^1 x^N
     174       ...
     175       y^N x^0, y^N x^1, ... y^N x^N
     176    */
     177    /* generate fitted values */
     178    x = xvec[0].elements;
     179    y = yvec[0].elements;
     180    zf = zfit;
     181    for (n = 0; n < xvec[0].Nelements; n++, x++, y++, zf++) {
     182      if (!finite(*x) || !finite(*y)) continue;
     183      *zf = 0;
     184      Y = X = 1;
     185      for (i = ny = 0; ny < nterm; ny++) {
     186        Y = X;
     187        for (nx = 0; nx < nterm - ny; nx++, i++) {
     188          *zf += b[i][0]*Y;
     189          Y = Y * (*y);
     190        }
    75191        X = X * (*x);
    76192      }
    77       Y = Y * (*y);
    78     }
    79   }
    80 
    81   /* add up the z values */
    82   x = xvec[0].elements;
    83   y = yvec[0].elements;
    84   z = zvec[0].elements;
    85   for (i = 0; i < xvec[0].Nelements; i++, x++, y++, z++) {
    86     Y = X = *z;
    87     for (N = 0, ny = 0; ny < nterm; ny++) {
    88       X = Y;
    89       for (nx = 0; nx < nterm - ny; nx++, N++) {
    90         b[N][0] += X;
    91         X = X * (*x);
    92       }
    93       Y = Y * (*y);
    94     }
    95   }
    96 
    97   /* re-sort mterm x mterm matrix to wterm matrix */
    98   for (k = j = 0; j < nterm; j++) {
    99     for (i = 0; i < nterm - j; i++, k++) {
    100       for (K = ny = 0; ny < nterm; ny++) {
    101         for (nx = 0; nx < nterm - ny; nx++, K++) {
    102           c[K][k] = s[nx+i][ny+j];
    103         }
    104       }
    105     }
    106   }
    107 
    108   gaussj (c, wterm, b, 1);
    109 
    110   fprintf (stderr, "z = ");
     193    }
     194
     195    /* measure fit residual scatter */
     196    x  = xvec[0].elements;
     197    y  = yvec[0].elements;
     198    z  = zvec[0].elements;
     199    zf = zfit;
     200    dZ = dZ2 = 0;
     201    for (i = Npt = 0; i < xvec[0].Nelements; i++, x++, y++, z++, zf++) {
     202      if (mask[i]) continue;
     203      if (!finite(*x) || !finite(*y)) continue;
     204      dZ  += (*z - *zf);
     205      dZ2 += SQ(*z - *zf);
     206      Npt ++;
     207    }
     208    mean  = dZ / Npt;
     209    sigma = sqrt (fabs(dZ2/Npt - SQ(mean)));
     210    maxsigma = ClipNSigma * sigma;
     211
     212    if (VERBOSE) fprintf (stderr, "mean: %g, sigma: %g, maxsigma: %g\n", mean, sigma, maxsigma);
     213
     214    /* mask outlier points */
     215    x  = xvec[0].elements;
     216    y  = yvec[0].elements;
     217    z  = zvec[0].elements;
     218    zf = zfit;
     219    Nmask = 0;
     220    for (i = 0; ClipNSigma && (i < xvec[0].Nelements); i++, x++, y++, z++, zf++) {
     221      dZ = (*z - *zf);
     222      if (fabs(dZ) > maxsigma) {
     223        mask[i] = TRUE;
     224        Nmask ++;
     225      } else {
     226        mask[i] = FALSE;
     227      }
     228    }
     229    if (VERBOSE) fprintf (stderr, "pass: %d, Nmask: %d\n", N, Nmask, ClipNSigma);
     230  }
     231
     232  if (!Quiet) fprintf (stderr, "z = ");
    111233  for (N = ny = 0; ny < nterm; ny++) {
    112234    for (nx = 0; nx < nterm - ny; nx++, N++) {
    113235      sprintf (name, "CX%dY%d", nx, ny);
    114236      set_variable (name, b[N][0]);
    115       fprintf (stderr, "%f x^%d y^%d  ", b[N][0], nx, ny);
     237      if (!Quiet) fprintf (stderr, "%f x^%d y^%d  ", b[N][0], nx, ny);
    116238    }
    117239  }
     
    119241  set_variable (name, (double) order);
    120242 
    121   fprintf (stderr, "\n");
     243  if (!Quiet) fprintf (stderr, "\n");
     244
     245  /* free internal data */
     246  free (zfit);
     247  free (mask);
     248
     249  for (i = 0; i < wterm; i++) {
     250    free (c[i]);
     251    free (b[i]);
     252  }
     253  free (b);
     254  free (c);
     255
     256  for (i = 0; i < mterm; i++) {
     257    free (s[i]);
     258  }
     259  free (s);
     260
    122261  return (TRUE);
    123 
    124262}
    125 
    126 
    127 
    128 
Note: See TracChangeset for help on using the changeset viewer.