00001 #ifndef Impala_Core_Histogram_FitWeibullMarginalOld_h
00002 #define Impala_Core_Histogram_FitWeibullMarginalOld_h
00003
00004
00005 #include <cmath>
00006
00007 namespace Impala
00008 {
00009 namespace Core
00010 {
00011 namespace Histogram
00012 {
00013
00014
00015
00016
00017 template<class HistT>
00018 class FitWeibullMarginalOld
00019 {
00020 public:
00021
00022
00023 FitWeibullMarginalOld(HistT* hist, int bins, double minrange, double maxrange)
00024 {
00025 mPrecision = 0.0;
00026 mMinval = minrange;
00027 mDx = (maxrange-minrange)/bins;
00028 DoFit(hist, bins);
00029 }
00030
00031 ~FitWeibullMarginalOld()
00032 {
00033 delete [] mHist;
00034 }
00035
00036 double
00037 Mu()
00038 {
00039 return mMu;
00040 }
00041
00042 double
00043 Beta()
00044 {
00045 return mBeta;
00046 }
00047
00048 double
00049 Gamma()
00050 {
00051 return mGamma;
00052 }
00053
00054 double
00055 A2()
00056 {
00057 return AndersonDarling();
00058 }
00059
00060 private:
00061
00062 void
00063 DoFit(HistT* orgHist, int orgBins)
00064 {
00065
00066 double x;
00067 double mode = 0.0;
00068 int bin0 = 0;
00069 int i;
00070 mMu = 0.0;
00071 for (i=0, x = mMinval+0.5*mDx; i<orgBins; i++, x += mDx)
00072 mMu += orgHist[i]*x;
00073 bin0 = (int)((mMu-mMinval)/mDx);
00074
00075
00076 mBins = bin0>orgBins/2 ? bin0 : orgBins-bin0;
00077 mHist = new HistT [mBins];
00078 for (i=0; i<mBins; i++)
00079 mHist[i] = 0;
00080 for (i=0; i<orgBins; i++)
00081 {
00082 int j = bin0 > i ? bin0-i-1 : i-bin0;
00083 mHist[j] += orgHist[i];
00084 }
00085
00086 double sumy(0), sumysq(0);
00087 double gammal, gammah;
00088 double xgm, gfm, tol;
00089
00090 mNorm = 0;
00091 for (i=0, x = mDx*0.5; i<mBins; i++, x += mDx)
00092 {
00093 if (mHist[i]>mPrecision)
00094 {
00095 double logy = log(x);
00096 sumy += mHist[i]*logy;
00097 sumysq += mHist[i]*logy*logy;
00098 mNorm += mHist[i];
00099 }
00100 }
00101
00102 sumy /= mNorm;
00103 sumysq /= mNorm;
00104 mGamma = 1.28/sqrt((sumysq-sumy*sumy)*mBins/(mBins-1.0));
00105 xgm = exp(sumy);
00106
00107 tol = 2.0*0.001*mGamma;
00108 gfm = GFunct(mGamma,xgm);
00109
00110 int its = 0;
00111
00112 if (gfm >= 0.0)
00113 {
00114 while (gfm > 0.0)
00115 {
00116 gammah = mGamma;
00117 mGamma /= 2.0;
00118 if (mGamma < tol)
00119 break;
00120 gfm = GFunct(mGamma,xgm);
00121 if (its++ > 30)
00122 break;
00123 }
00124 gammal = mGamma;
00125 }
00126 its = 0;
00127 while (gfm < 0.0)
00128 {
00129 gammal = mGamma;
00130 mGamma *= 2.0;
00131 gfm = GFunct(mGamma,xgm);
00132 if (its++ > 30)
00133 break;
00134 }
00135 gammah = mGamma;
00136
00137 its = 0;
00138 while ((gammah-gammal) > tol)
00139 {
00140 mGamma = (gammal+gammah)/2.0;
00141 gfm = GFunct(mGamma,xgm);
00142 if (gfm >= 0.0)
00143 gammah = mGamma;
00144 else
00145 gammal = mGamma;
00146 if (its++ > 30)
00147 break;
00148 }
00149
00150 mGamma = (gammal+gammah)/2.0;
00151 mBeta = BetaEst(mGamma,xgm);
00152 }
00153
00154 double
00155 BetaEst(double gamma, double xgm) const
00156 {
00157 double sum(0);
00158 double ddx = mDx/xgm;
00159 double x = 0.5*ddx;
00160
00161 for (int i=0; i<mBins; i++, x += ddx)
00162 if (mHist[i]>mPrecision)
00163 sum += pow(x, gamma)*mHist[i];
00164
00165 return xgm*pow(sum/mNorm, 1./gamma);
00166 }
00167
00168 double
00169 GFunct(double gamma, double xgm) const
00170 {
00171 double sum(0);
00172 double beta = BetaEst(gamma, xgm);
00173 double ddx = mDx/beta;
00174 double x = 0.5*ddx;
00175
00176 for (int i=0; i<mBins; i++, x += ddx)
00177 if (mHist[i]>mPrecision)
00178 sum += log(x*beta)*(pow(x, gamma)-1.0)*mHist[i];
00179
00180 return sum/mNorm-1./gamma;
00181 }
00182
00183 double
00184 AndersonDarling() const
00185 {
00186 double A2 = 0;
00187 double x;
00188 int i, bins = 0;
00189
00190 double Fi = 0.0;
00191
00192 for (i=0, x = mDx; i<mBins; i++, x += mDx)
00193 {
00194 if (mHist[i]>mPrecision)
00195 {
00196 double xt = pow(x/mBeta, mGamma);
00197 double F = exp(-xt);
00198 double dF = (mGamma/mBeta)*pow(x/mBeta, mGamma-1.0)*F*mDx;
00199
00200 Fi += mHist[i]/mNorm;
00201 F = 1.0-F;
00202 if ((F>0.0) && (F<1.0))
00203 A2 += (pow(Fi-F,2.0)/(F*(1-F)))*dF;
00204 bins++;
00205 }
00206 }
00207
00208 return bins*A2;
00209 }
00210
00211 HistT* mHist;
00212 int mBins;
00213
00214 double mMinval;
00215 double mDx;
00216 double mNorm;
00217
00218 double mMu;
00219 double mBeta;
00220 double mGamma;
00221 double mPrecision;
00222 };
00223
00224 }
00225 }
00226 }
00227
00228 #endif