irplib_detmon_body.h
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #define TYPE_ADD(a) CONCAT2X(a, CPL_TYPE)
00029
00030 static cpl_error_code
00031 TYPE_ADD(irplib_ksigma_clip)(const CPL_TYPE * pi,
00032 int llx,
00033 int lly,
00034 int urx,
00035 int ury,
00036 int nx,
00037 double var_sum,
00038 int npixs,
00039 double kappa,
00040 int nclip,
00041 double tolerance,
00042 double * mean,
00043 double * stdev)
00044 {
00045 int pos0 = (llx - 1) + (lly - 1) * nx;
00046 double nb = (double) npixs;
00047
00048 double lo_cut = *mean - kappa * (*stdev);
00049 double hi_cut = *mean + kappa * (*stdev);
00050
00051 double lo_cut_p = lo_cut;
00052 double hi_cut_p = hi_cut;
00053
00054 double c_var_sum;
00055 double c_mean = 0;
00056 double c_stdev = 0;
00057
00058 int iclip;
00059
00060 for (iclip = 0; iclip < nclip; iclip++) {
00061 int pos = pos0;
00062 int i, j;
00063
00064 c_var_sum = var_sum;
00065 c_mean = *mean;
00066 c_stdev = *stdev;
00067 nb = npixs;
00068
00069 for (j = lly - 1; j < ury; j++, pos += (nx - urx + llx - 1)) {
00070 for (i = llx - 1; i < urx; i++, pos++) {
00071 if (pi[pos] > hi_cut || pi[pos] < lo_cut) {
00072 const double delta = (double)pi[pos] - c_mean;
00073
00074 c_var_sum -= nb * delta * delta / (nb - 1.0);
00075 c_mean -= delta / (nb - 1.0);
00076 nb = nb - 1.0;
00077 }
00078 }
00079 }
00080
00081 if (nb == 1.0 || c_var_sum < 0.0) {
00082 cpl_msg_error(cpl_func, "Iteration %d: Too many pixels were "
00083 "removed. This may cause unexpected behaviour. "
00084 "Please set a lower number of iterations "
00085 "or increase the value of kappa\n", iclip);
00086 cpl_error_set(cpl_func, CPL_ERROR_DIVISION_BY_ZERO);
00087 } else {
00088 c_stdev = sqrt(c_var_sum / (nb - 1.0));
00089 }
00090
00091 lo_cut = c_mean - kappa * c_stdev;
00092 hi_cut = c_mean + kappa * c_stdev;
00093
00094 if(fabs(lo_cut - lo_cut_p) < tolerance &&
00095 fabs(hi_cut - hi_cut_p) < tolerance) {
00096 break;
00097 } else {
00098 lo_cut_p = lo_cut;
00099 hi_cut_p = hi_cut;
00100 }
00101 }
00102
00103 *mean = c_mean;
00104 *stdev = c_stdev;
00105
00106 return cpl_error_get_code();
00107 }