Changeset 40754
- Timestamp:
- May 25, 2019, 3:28:51 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ohana.20190329/src/opihi/mana/deimos_fitprofile.c
r40753 r40754 4 4 typedef enum {MODE_UPPER, MODE_LOWER} SigmoidMode; 5 5 6 void sigmoid_fit (Vector *xprofile, Vector *fprofile, Vector *oprofile, double *par, int Npar, SigmoidMode mode, double limit); 6 void sigmoid_fit (opihi_flt *xprofile, opihi_flt *fprofile, opihi_flt *wprofile, opihi_flt *oprofile, int Npts, opihi_flt *par, int Npar, FitFunc *FUNC); 7 void sigmoid_fit_irls (opihi_flt *xprofile, opihi_flt *fprofile, opihi_flt *wprofile, opihi_flt *oprofile, int NptsAll, opihi_flt *par, int Npar, SigmoidMode mode, double limit); 7 8 8 9 opihi_flt fsigmoidDeimos (opihi_flt, opihi_flt *, int, opihi_flt *); 9 10 opihi_flt rsigmoidDeimos (opihi_flt, opihi_flt *, int, opihi_flt *); 11 12 double deimos_weight_cauchy (double x); 10 13 11 14 // use these globals to carry into sigmoid_fit 12 15 int VERBOSE = FALSE; 13 16 int QUIET = FALSE; 17 int MaxIterations = 10; 14 18 15 19 int deimos_fitprofile (int argc, char **argv) { … … 29 33 Vector *xprofile = NULL; 30 34 Vector *fprofile = NULL; 35 Vector *wprofile = NULL; 31 36 32 37 QUIET = FALSE; … … 44 49 remove_argument (N, &argc, argv); 45 50 } 46 47 if (argc != 5) goto usage; 51 MaxIterations = 10; 52 if ((N = get_argument (argc, argv, "-max-iterations"))) { 53 remove_argument (N, &argc, argv); 54 MaxIterations = atof(argv[N]); 55 remove_argument (N, &argc, argv); 56 } 57 58 if (argc != 6) goto usage; 48 59 if ((xprofile = SelectVector (argv[1], OLDVECTOR, TRUE)) == NULL) return (FALSE); 49 60 if ((fprofile = SelectVector (argv[2], OLDVECTOR, TRUE)) == NULL) return (FALSE); 61 if ((wprofile = SelectVector (argv[3], OLDVECTOR, TRUE)) == NULL) return (FALSE); 50 62 if (xprofile->Nelements != fprofile->Nelements) goto usage; 63 if (xprofile->Nelements != wprofile->Nelements) goto usage; 51 64 52 65 // supplied guess for boundaries 53 double Xs = atof(argv[ 3]);54 double Xe = atof(argv[ 4]);66 double Xs = atof(argv[4]); 67 double Xe = atof(argv[5]); 55 68 56 69 // output vectors of fits … … 94 107 par[2] = Sky; 95 108 par[3] = BckL; 96 97 sigmoid_fit (xprofile, fprofile, Lprofile, par, Npar, MODE_LOWER, Xmid); 109 sigmoid_fit_irls (xprofile->elements.Flt, fprofile->elements.Flt, wprofile->elements.Flt, Lprofile->elements.Flt, xprofile->Nelements, par, Npar, MODE_LOWER, Xmid); 110 set_variable ("sigmoid_left_center", par[0]); 111 set_variable ("sigmoid_left_sigma", par[1]); 112 set_variable ("sigmoid_left_top", par[2]); 113 set_variable ("sigmoid_left_bottom", par[3]); 98 114 99 115 par[0] = Xe; … … 101 117 par[2] = Sky; 102 118 par[3] = BckR; 103 104 sigmoid_fit (xprofile, fprofile, Rprofile, par, Npar, MODE_UPPER, Xmid); 119 sigmoid_fit_irls (xprofile->elements.Flt, fprofile->elements.Flt, wprofile->elements.Flt, Rprofile->elements.Flt, xprofile->Nelements, par, Npar, MODE_UPPER, Xmid); 120 set_variable ("sigmoid_right_center", par[0]); 121 set_variable ("sigmoid_right_sigma", par[1]); 122 set_variable ("sigmoid_right_top", par[2]); 123 set_variable ("sigmoid_right_bottom", par[3]); 105 124 106 125 return TRUE; 107 126 108 127 usage: 109 gprint (GP_ERR, "USAGE: deimos fitprofile xprof fprof Xs Xe\n");128 gprint (GP_ERR, "USAGE: deimos fitprofile xprof fprof wprof Xs Xe\n"); 110 129 return FALSE; 111 130 } … … 173 192 } 174 193 175 void sigmoid_fit (Vector *xprofile, Vector *fprofile, Vector *oprofile, double *par, int Npar, SigmoidMode mode, double limit) { 176 177 int Nelements = xprofile->Nelements; 178 179 ALLOCATE_PTR (xtemp, opihi_flt, Nelements); 180 ALLOCATE_PTR (ytemp, opihi_flt, Nelements); 181 ALLOCATE_PTR (wtemp, opihi_flt, Nelements); 194 # define FIT_TOLERANCE 1e-4 195 # define FLT_TOLERANCE 1e-6 196 197 // wprofile is the true poisson error 198 void sigmoid_fit_irls (opihi_flt *xprofile, opihi_flt *fprofile, opihi_flt *wprofile, opihi_flt *oprofile, int NptsAll, opihi_flt *par, int Npar, SigmoidMode mode, double limit) { 199 200 FitFunc *FUNC = (mode == MODE_LOWER) ? fsigmoidDeimos : rsigmoidDeimos; 201 202 ALLOCATE_PTR (par_old, opihi_flt, Npar); 203 204 // allocate these as global static in this file? 205 ALLOCATE_PTR (xtemp, opihi_flt, NptsAll); 206 ALLOCATE_PTR (ytemp, opihi_flt, NptsAll); 207 ALLOCATE_PTR (wtemp, opihi_flt, NptsAll); 208 ALLOCATE_PTR (otemp, opihi_flt, NptsAll); 182 209 183 210 // extract the points on the right side and fit 184 // XXX error model is pure poisson (allow external errors)185 186 211 int Npts = 0; 187 for (int i = 0; i < N elements; i++) {188 int keep = (mode == MODE_UPPER) ^ (xprofile ->elements.Flt[i] < limit);212 for (int i = 0; i < NptsAll; i++) { 213 int keep = (mode == MODE_UPPER) ^ (xprofile[i] < limit); 189 214 if (keep) { 190 xtemp[Npts] = xprofile ->elements.Flt[i];191 ytemp[Npts] = fprofile ->elements.Flt[i];192 wtemp[Npts] = 1.0 / (fabs(fprofile->elements.Flt[i] + 0.01));215 xtemp[Npts] = xprofile[i]; 216 ytemp[Npts] = fprofile[i]; 217 wtemp[Npts] = (wprofile[i] == 0.0) ? 1.0 : wprofile[i]; // crude 193 218 Npts ++; 194 219 } 195 220 } 196 221 197 FitFunc *FUNC = (mode == MODE_LOWER) ? fsigmoidDeimos : rsigmoidDeimos; 198 199 double ochisq = mrqinit (xtemp, ytemp, wtemp, Npts, par, Npar, FUNC, VERBOSE); 222 // define initial weights as 1.0 223 ALLOCATE_PTR (wt, opihi_flt, Npts); 224 for (int i = 0; i < Npts; i++) { 225 wt[i] = 1.0 / SQ(wtemp[i]); 226 } 227 228 // initial fit with ordinary least-squares 229 // otemp is the fitted value of the function at xtemp 230 sigmoid_fit (xtemp, ytemp, wt, otemp, Npts, par, Npar, FUNC); 231 232 int converged = FALSE; 233 for (int iterations = 0; !converged && (iterations < MaxIterations); iterations++) { 234 235 for (int i = 0; i < Npts; i++) { 236 wt[i] = deimos_weight_cauchy ((ytemp[i] - otemp[i]) / wtemp[i]) / SQ(wtemp[i]); 237 } 238 239 sigmoid_fit (xtemp, ytemp, wt, otemp, Npts, par, Npar, FUNC); 240 241 // save this solution 242 for (int i = 0; i < Npar; i++) { 243 par_old[i] = par[i]; 244 } 245 246 converged = TRUE; 247 for (int i = 0; i < Npts; i++) { 248 if ((fabs(par[i] - par_old[i]) > FIT_TOLERANCE * fabs(par[i])) && 249 (fabs(par[i] - par_old[i]) > FLT_TOLERANCE)) 250 converged = FALSE; 251 } 252 } 253 254 for (int i = 0; i < NptsAll; i++) { 255 oprofile[i] = FUNC (xprofile[i], par, Npar, NULL); 256 } 257 258 FREE (xtemp); 259 FREE (ytemp); 260 FREE (wtemp); 261 FREE (otemp); 262 263 FREE (par_old); 264 FREE (wt); 265 } 266 267 void sigmoid_fit (opihi_flt *xprofile, opihi_flt *yprofile, opihi_flt *wprofile, opihi_flt *oprofile, int Npts, opihi_flt *par, int Npar, FitFunc *FUNC) { 268 269 double ochisq = mrqinit (xprofile, yprofile, wprofile, Npts, par, Npar, FUNC, VERBOSE); 200 270 double dchisq = ochisq + 2*Npts; 201 271 202 272 int Niter; 203 273 for (Niter = 0; (Niter < 20) && ((dchisq > 0.1*(Npts - Npar)) || (dchisq <= 0.0)); Niter++) { 204 double chisq = mrqmin (x temp, ytemp, wtemp, Npts, par, Npar, FUNC, VERBOSE);274 double chisq = mrqmin (xprofile, yprofile, wprofile, Npts, par, Npar, FUNC, VERBOSE); 205 275 dchisq = ochisq - chisq; 206 276 ochisq = chisq; … … 210 280 211 281 if (!QUIET) gprint (GP_LOG, "sigmoid @ %f (%f) : top %f bottom %f\n", par[0], par[1], par[2], par[3]); 212 for (int i = 0; i < Nelements; i++) { 213 oprofile[0].elements.Flt[i] = FUNC (xprofile[0].elements.Flt[i], par, Npar, NULL); 214 } 215 216 if (mode == MODE_LOWER) { 217 set_variable ("sigmoid_left_center", par[0]); 218 set_variable ("sigmoid_left_sigma", par[1]); 219 set_variable ("sigmoid_left_top", par[2]); 220 set_variable ("sigmoid_left_bottom", par[3]); 221 } else { 222 set_variable ("sigmoid_right_center", par[0]); 223 set_variable ("sigmoid_right_sigma", par[1]); 224 set_variable ("sigmoid_right_top", par[2]); 225 set_variable ("sigmoid_right_bottom", par[3]); 226 } 282 283 for (int i = 0; i < Npts; i++) { 284 oprofile[i] = FUNC (xprofile[i], par, Npar, NULL); 285 } 286 227 287 mrqfree (Npar); 228 229 FREE (xtemp);230 FREE (ytemp);231 FREE (wtemp);232 233 288 } 289 290 double deimos_weight_cauchy (double x) { 291 double r = x / 2.385; 292 return (1.0 / (1.0 + SQ(r))); 293 } 294
Note:
See TracChangeset
for help on using the changeset viewer.
