00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "BCMath.h"
00011
00012 #include <TMath.h>
00013
00014
00015
00016 double BCMath::LogGaus(double x, double mean, double sigma, bool norm)
00017 {
00018
00019
00020
00021 if(sigma==0.)
00022 return 0;
00023
00024
00025
00026 if(sigma<0.)
00027 sigma *= -1.;
00028
00029 double arg = (x-mean)/sigma;
00030 double result = -.5 * arg * arg;
00031
00032
00033
00034 if(!norm)
00035 return result;
00036
00037
00038
00039 return result - log( sqrt( 2.* M_PI ) * sigma );
00040
00041 }
00042
00043
00044
00045 double BCMath::LogPoisson(double x, double par)
00046 {
00047 if (par > 899)
00048 return BCMath::LogGaus(x,par,sqrt(par),true);
00049
00050 if (x<0)
00051 return 0;
00052
00053 if (x == 0.)
00054 return -par;
00055
00056
00057 return x*log(par)-par-BCMath::ApproxLogFact(x);
00058 }
00059
00060
00061
00062 double BCMath::ApproxBinomial(int n, int k, double p)
00063 {
00064
00065 return exp( BCMath::LogApproxBinomial(n, k, p) );
00066
00067 }
00068
00069
00070
00071 double BCMath::LogApproxBinomial(int n, int k, double p)
00072 {
00073
00074
00075
00076 if(n<k)
00077 {
00078 int a=n;
00079 n=k;
00080 k=a;
00081 }
00082
00083 return BCMath::LogBinomFactor(n,k) + (double)k*log(p) + (double)(n-k)*log(1.-p);
00084
00085 }
00086
00087
00088
00089 double BCMath::LogBinomFactor(int n, int k)
00090 {
00091
00092
00093
00094 if(n<k)
00095 {
00096 int a=n;
00097 n=k;
00098 k=a;
00099 }
00100
00101 if(n==k || k==0) return 0.;
00102 if(k==1 || k==n-1) return log((double)n);
00103
00104
00105
00106 int flimit = 100;
00107
00108
00109
00110 if(n<flimit || (n-k)<5) return BCMath::LogNoverK(n,k);
00111
00112
00113
00114 return BCMath::ApproxLogFact((double)n) - BCMath::ApproxLogFact((double)k) - BCMath::ApproxLogFact((double)(n-k));
00115
00116 }
00117
00118
00119
00120 double BCMath::ApproxLogFact(double x)
00121 {
00122
00123 int flimit=100;
00124
00125 if(x>flimit)
00126 return x*log(x) - x + .5*log(2.*M_PI*x) - 1./(12.*x);
00127
00128 else
00129 return BCMath::LogFact((int)x);
00130
00131 }
00132
00133
00134 double BCMath::LogFact(int n)
00135 {
00136
00137 double ln = 0.;
00138
00139 for(int i=1;i<=n;i++)
00140 ln += log((double)i);
00141
00142 return ln;
00143 }
00144
00145
00146
00147 double BCMath::LogNoverK(int n, int k)
00148 {
00149
00150
00151
00152 if(n<k)
00153 {
00154 int a = n;
00155 n = k;
00156 k = a;
00157 }
00158
00159 if(n==k || k==0) return 0.;
00160 if(k==1 || k==n-1) return log((double)n);
00161
00162 int lmax = BCMath::Max(k,n-k);
00163 int lmin = BCMath::Min(k,n-k);
00164
00165 double ln = 0.;
00166
00167 for(int i=n;i>lmax;i--)
00168 ln += log((double)i);
00169 ln -= BCMath::LogFact(lmin);
00170
00171 return ln;
00172
00173 }
00174
00175
00176
00177 int BCMath::Nint(double x)
00178 {
00179
00180
00181
00182 int i;
00183
00184 if (x >= 0)
00185 {
00186 i = (int)(x + .5);
00187
00188 if (x + .5 == (double)i && i & 1)
00189 i--;
00190 }
00191
00192 else
00193 {
00194 i = int(x - 0.5);
00195
00196 if (x - 0.5 == double(i) && i & 1)
00197 i++;
00198 }
00199
00200 return i;
00201
00202 }
00203
00204
00205
00206 double BCMath::rms(int n, const double *a)
00207 {
00208
00209 if (n <= 0 || !a)
00210 return 0;
00211
00212 double sum = 0., sum2 = 0.;
00213
00214 for (int i = 0; i < n; i++)
00215 {
00216 sum += a[i];
00217 sum2 += a[i] * a[i];
00218 }
00219
00220 double n1 = 1./(double)n;
00221 double mean = sum * n1;
00222 double rms = sqrt(fabs(sum2 * n1 - mean * mean));
00223
00224 return rms;
00225
00226 }
00227
00228
00229
00230 double BCMath::LogBreitWignerNonRel(double x, double mean, double Gamma, bool norm)
00231 {
00232
00233 double bw = log(Gamma) - log( (x - mean) * (x - mean) + Gamma * Gamma / 4.0);
00234
00235 if (norm)
00236 return bw - log(2. * M_PI);
00237 else
00238 return bw;
00239
00240 }
00241
00242