IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Dec 11, 2015, 9:12:57 AM (11 years ago)
Author:
eugene
Message:

adding IRLS versions of fitpm and fitplx

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Ohana/src/relastro/src/FitPM_IRLS.c

    r39241 r39246  
    1111  int i,j;
    1212
    13   int p   = 4;
    14   int n   = 2 * Npoints;
    15   int dof = n - p;
    16  
    17   // data->A,B,Cov,Beta,Beta_prev are allocated outside by FitAstromDataInit()
    18   // points->Wx,Wy,rx,ry,u are elements of FitAstromPoint
     13  int Ndof = 2 * Npoints - data->Nterms;
    1914 
    2015  // Convert the measurement errors into initial weights.
    2116  for (i = 0; i < Npoints; i++) {
    22     // points[i].Wx = 1 / points[i].dX;
    23     // points[i].Wy = 1 / points[i].dY;
    2417    points[i].Wx = (fabs(points[i].dX) < 0.0001) ? 1.0 : 1 / SQ(points[i].dX);
    2518    points[i].Wy = (fabs(points[i].dY) < 0.0001) ? 1.0 : 1 / SQ(points[i].dY);
     
    3932    sigma_ols += SQ(points[i].rx) + SQ(points[i].ry);
    4033  }
    41   sigma_ols = sqrt(sigma_ols / dof);
     34  sigma_ols = sqrt(sigma_ols / (float)Ndof);
    4235
    4336  // Save OLS covariance and Beta (solution vector, which is actually also saved in fit)
     
    10194  }
    10295
    103   // this section calculates the formal error on the weighted fit using the covariance values
     96  // calculate the weight thresholds to mask the bad points:
    10497  double Sum_Wx = 0.0;
    10598  double Sum_Wy = 0.0;
    106   if (1) {
     99  for (i = 0; i < Npoints; i++) {
     100    points[i].Wx = weight_cauchy(points[i].rx / points[i].dX);
     101    points[i].Wy = weight_cauchy(points[i].ry / points[i].dY);
     102   
     103    Sum_Wx += points[i].Wx;
     104    Sum_Wy += points[i].Wy;
     105  }
     106  double WxThreshold = WEIGHT_THRESHOLD * Sum_Wx / (1.0 * Npoints);
     107  double WyThreshold = WEIGHT_THRESHOLD * Sum_Wy / (1.0 * Npoints);
     108
     109  // set a mask (which can be used by the bootstrap resampling analysis)
     110  for (i = 0; i < Npoints; i++) {
     111    // keep if either is above threshold?
     112    // drop if either is below threshold?
     113    // points are marked as keep by default
     114    if ((points[i].Wx < WxThreshold) || (points[i].Wy < WyThreshold)) {
     115      points[i].mask = 1; // keep point if mask == 0
     116    }
     117  }
     118
     119  // this section calculates the formal error on the weighted fit using the covariance values
     120  // NOTE EAM: in tests (fitpm.c), they seem to be too large by a factor of ~5.37
     121  if (data->getError) {
    107122    double ax = 0.0, ay = 0.0;
    108123    double bx = 0.0, by = 0.0;
    109     double lambda = 0.0;
     124
    110125    for (i = 0; i < Npoints; i++) {
    111       points[i].Wx = weight_cauchy(points[i].rx / points[i].dX);
    112       points[i].Wy = weight_cauchy(points[i].ry / points[i].dY);
    113    
    114126      ax += dpsi_cauchy(points[i].rx / points[i].dX);
    115127      ay += dpsi_cauchy(points[i].ry / points[i].dY);
     
    117129      bx += SQ(points[i].Wx);
    118130      by += SQ(points[i].Wy);
    119 
    120       Sum_Wx += points[i].Wx;
    121       Sum_Wy += points[i].Wy;
    122131    }
    123132    ax /= 1.0 * Npoints;  // mean(psi_dot(r))
    124133    ay /= 1.0 * Npoints;
    125     bx /= 1.0 * (Npoints - p); // mean(psi^2(r)) * (N / (N-p))
    126     by /= 1.0 * (Npoints - p);
    127  
    128     double sigma_robust_x = lambda * sqrt(bx) * sigma_hat * 2.385 / ax;
    129     double sigma_robust_y = lambda * sqrt(by) * sigma_hat * 2.385 / ay;
     134    bx /= 1.0 * (Npoints - data->Nterms); // mean(psi^2(r)) * (N / (N-p))
     135    by /= 1.0 * (Npoints - data->Nterms);
     136 
     137    double lambda_x = 1.0 + (data->Nterms / Npoints) * (1 - ax) / ax;
     138    double lambda_y = 1.0 + (data->Nterms / Npoints) * (1 - ay) / ay;
     139 
     140    double sigma_robust_x = lambda_x * sqrt(bx) * sigma_hat * 2.385 / ax;
     141    double sigma_robust_y = lambda_y * sqrt(by) * sigma_hat * 2.385 / ay;
    130142
    131143    // This is actually sigma^2, as that's the factor in the covariance (dumouchel 4.1)
    132     double sigma_final_x  = MAX(SQ(sigma_robust_x), (n * SQ(sigma_robust_x) + SQ(p * sigma_ols)) / (n + SQ(p)));
    133     double sigma_final_y  = MAX(SQ(sigma_robust_y), (n * SQ(sigma_robust_y) + SQ(p * sigma_ols)) / (n + SQ(p)));
     144    double sigma_final_x  = MAX(SQ(sigma_robust_x), (2 * Npoints * SQ(sigma_robust_x) + SQ(data->Nterms * sigma_ols)) / (2 * Npoints + SQ(data->Nterms)));
     145    double sigma_final_y  = MAX(SQ(sigma_robust_y), (2 * Npoints * SQ(sigma_robust_y) + SQ(data->Nterms * sigma_ols)) / (2 * Npoints + SQ(data->Nterms)));
    134146
    135147    fit[0].dRo = sqrt(data->Cov[0][0]);
     
    144156  }
    145157
    146   // set a mask (which can be used by the bootstrap resampling analysis)
    147   double WxThreshold = WEIGHT_THRESHOLD * Sum_Wx / (1.0 * Npoints);
    148   double WyThreshold = WEIGHT_THRESHOLD * Sum_Wy / (1.0 * Npoints);
    149 
    150   for (i = 0; i < Npoints; i++) {
    151     // keep if either is above threshold?
    152     // drop if either is below threshold?
    153     // points are marked as keep by default
    154     if ((points[i].Wx < WxThreshold) || (points[i].Wy < WyThreshold)) {
    155       points[i].mask = 1;
    156     }
    157   }
    158 
    159158  // (optionally) add up the chi square for the fit, only counting the unmasked points
    160159  double chisq = 0.0;
     
    162161  for (i = 0; i < Npoints; i++) {
    163162    if (points[i].mask) continue;
     163    fit[0].Nfit ++;
    164164     
    165     double Xf = fit[0].Ro + fit[0].uR*points[i].T;
    166     double Yf = fit[0].Do + fit[0].uD*points[i].T;
    167     double wx = (fabs(points[i].dX) < 0.0001) ? 1.0 : 1.0 / SQ(points[i].dX);
    168     double wy = (fabs(points[i].dY) < 0.0001) ? 1.0 : 1.0 / SQ(points[i].dY);
    169     chisq += SQ(points[i].X - Xf) * wx;
    170     chisq += SQ(points[i].Y - Yf) * wy;
    171     fit[0].Nfit ++;
    172   }
    173    
    174   // the reduced chisq is divided by (Ndof = 2*Nfit - 4)
    175   fit[0].chisq = chisq / (2.0*fit[0].Nfit - 4.0);
     165    if (data->getChisq) {
     166      double Xf = fit[0].Ro + fit[0].uR*points[i].T;
     167      double Yf = fit[0].Do + fit[0].uD*points[i].T;
     168      double wx = (fabs(points[i].dX) < 0.0001) ? 1.0 : 1.0 / SQ(points[i].dX);
     169      double wy = (fabs(points[i].dY) < 0.0001) ? 1.0 : 1.0 / SQ(points[i].dY);
     170      chisq += SQ(points[i].X - Xf) * wx;
     171      chisq += SQ(points[i].Y - Yf) * wy;
     172    }
     173  }
     174   
     175  // the reduced chisq is divided by (Ndof = 2*Nfit - Nterms)
     176  fit[0].chisq = chisq / (2.0*fit[0].Nfit - data->Nterms);
    176177
    177178  return (TRUE);
Note: See TracChangeset for help on using the changeset viewer.