SNAP Library 2.0, Developer Reference
2013-05-13 16:33:57
SNAP, a general purpose, high performance system for analysis and manipulation of large networks
|
00001 00002 // Mathematical-Utilities 00003 double TMath::E=2.71828182845904523536; 00004 double TMath::Pi=3.14159265358979323846; 00005 double TMath::LogOf2=log(double(2)); 00006 00008 // Special-Functions 00009 void TSpecFunc::GammaPSeries/*gser*/( 00010 double& gamser, const double& a, const double& x, double& gln){ 00011 static const int ITMAX=100; 00012 static const double EPS=3.0e-7; 00013 int n; 00014 double sum, del, ap; 00015 00016 gln=LnGamma(a); 00017 if (x <= 0.0){ 00018 IAssert(x>=0); /*if (x < 0.0) nrerror("x less than 0 in routine gser");*/ 00019 gamser=0.0; 00020 return; 00021 } else { 00022 ap=a; 00023 del=sum=1.0/a; 00024 for (n=1; n<=ITMAX; n++){ 00025 ++ap; 00026 del *= x/ap; 00027 sum += del; 00028 if (fabs(del) < fabs(sum)*EPS){ 00029 gamser=sum*exp(-x+a*log(x)-(gln)); 00030 return; 00031 } 00032 } 00033 Fail; /*nrerror("a too large, ITMAX too small in routine gser");*/ 00034 return; 00035 } 00036 } 00037 00038 void TSpecFunc::GammaQContFrac/*gcf*/( 00039 double& gammcf, const double& a, const double& x, double& gln){ 00040 static const int ITMAX=100; 00041 static const double EPS=3.0e-7; 00042 static const double FPMIN=1.0e-30; 00043 int i; 00044 double an, b, c, d, del, h; 00045 00046 gln=LnGamma(a); 00047 b=x+1.0-a; 00048 c=1.0/FPMIN; 00049 d=1.0/b; 00050 h=d; 00051 for (i=1;i<=ITMAX;i++){ 00052 an = -i*(i-a); 00053 b += 2.0; 00054 d=an*d+b; 00055 if (fabs(d) < FPMIN) d=FPMIN; 00056 c=b+an/c; 00057 if (fabs(c) < FPMIN) c=FPMIN; 00058 d=1.0/d; 00059 del=d*c; 00060 h *= del; 00061 if (fabs(del-1.0) < EPS) break; 00062 } 00063 IAssert(i<=ITMAX); 00064 /*if (i > ITMAX) nrerror("a too large, ITMAX too small in gcf");*/ 00065 gammcf=exp(-x+a*log(x)-(gln))*h; 00066 } 00067 00068 double TSpecFunc::GammaQ/*gammq*/(const double& a, const double& x){ 00069 IAssert((x>=0)&&(a>0)); 00070 double gamser, gammcf, gln; 00071 if (x<(a+1.0)){ 00072 GammaPSeries(gamser,a,x,gln); 00073 return 1.0-gamser; 00074 } else { 00075 GammaQContFrac(gammcf,a,x,gln); 00076 return gammcf; 00077 } 00078 } 00079 00080 double TSpecFunc::LnGamma/*gammln*/(const double& xx){ 00081 double x, y, tmp, ser; 00082 static double cof[6]={76.18009172947146,-86.50532032941677, 00083 24.01409824083091,-1.231739572450155, 00084 0.1208650973866179e-2,-0.5395239384953e-5}; 00085 int j; 00086 00087 y=x=xx; 00088 tmp=x+5.5; 00089 tmp -= (x+0.5)*log(tmp); 00090 ser=1.000000000190015; 00091 for (j=0;j<=5;j++) ser += cof[j]/++y; 00092 return -tmp+log(2.5066282746310005*ser/x); 00093 } 00094 00095 double TSpecFunc::LnComb(const int& n, const int& k){ 00096 return LnGamma(n+1)-LnGamma(k+1)-LnGamma(n-k+1); 00097 } 00098 00099 double TSpecFunc::BetaCf(const double& a, const double& b, const double& x){ 00100 static const double MAXIT=100; 00101 static const double EPS=3.0e-7; 00102 static const double FPMIN=1.0e-30; 00103 int m,m2; 00104 double aa,c,d,del,h,qab,qam,qap; 00105 00106 qab=a+b; 00107 qap=a+1.0; 00108 qam=a-1.0; 00109 c=1.0; 00110 d=1.0-qab*x/qap; 00111 if (fabs(d) < FPMIN) d=FPMIN; 00112 d=1.0/d; 00113 h=d; 00114 for (m=1;m<=MAXIT;m++) { 00115 m2=2*m; 00116 aa=m*(b-m)*x/((qam+m2)*(a+m2)); 00117 d=1.0+aa*d; 00118 if (fabs(d) < FPMIN) d=FPMIN; 00119 c=1.0+aa/c; 00120 if (fabs(c) < FPMIN) c=FPMIN; 00121 d=1.0/d; 00122 h *= d*c; 00123 aa = -(a+m)*(qab+m)*x/((a+m2)*(qap+m2)); 00124 d=1.0+aa*d; 00125 if (fabs(d) < FPMIN) d=FPMIN; 00126 c=1.0+aa/c; 00127 if (fabs(c) < FPMIN) c=FPMIN; 00128 d=1.0/d; 00129 del=d*c; 00130 h *= del; 00131 if (fabs(del-1.0) < EPS) break; 00132 } 00133 if (m > MAXIT){Fail;}// a or b too big, or MAXIT too small in betacf 00134 return h; 00135 } 00136 00137 double TSpecFunc::BetaI(const double& a, const double& b, const double& x){ 00138 double bt; 00139 00140 if (x < 0.0 || x > 1.0){Fail;} // Bad x in routine betai 00141 if (x == 0.0 || x == 1.0) bt=0.0; 00142 else 00143 bt=exp(LnGamma(a+b)-LnGamma(a)-LnGamma(b)+a*log(x)+b*log(1.0-x)); 00144 if (x < (a+1.0)/(a+b+2.0)) 00145 return bt*BetaCf(a,b,x)/a; 00146 else 00147 return 1.0-bt*BetaCf(b,a,1.0-x)/b; 00148 } 00149 00150 void TSpecFunc::LinearFit( 00151 const TVec<TFltPr>& XY, double& A, double& B, 00152 double& SigA, double& SigB, double& Chi2, double& R2) { 00153 // y = a + bx :: SigA (SigB): A's uncertainty; Chi2: std dev on all points 00154 int i; 00155 double t, sxoss, sx = 0.0, sy = 0.0, st2 = 0.0, ss, sigdat; 00156 00157 A = B = SigA = SigB = Chi2 = 0.0; 00158 for (i = 0; i < XY.Len(); i++) { 00159 sx += XY[i].Val1; 00160 sy += XY[i].Val2; 00161 } 00162 ss = XY.Len(); 00163 sxoss = sx / ss; 00164 for (i = 0; i <XY.Len(); i++) { 00165 t = XY[i].Val1 - sxoss; 00166 st2 += t*t; 00167 B += t * XY[i].Val2; 00168 } 00169 B /= st2; 00170 A = (sy - sx * B) / ss; 00171 SigA = sqrt((1.0 + sx * sx / (ss * st2)) / ss); 00172 SigB = sqrt(1.0 / st2); 00173 for (i = 0; i < XY.Len(); i++) 00174 Chi2 += TMath::Sqr(XY[i].Val2 - A - B * XY[i].Val1); 00175 sigdat = sqrt(Chi2 / (XY.Len() - 2)); 00176 SigA *= sigdat; 00177 SigB *= sigdat; 00178 00179 // calculate R squared 00180 { double N = XY.Len(), sXY=0.0, sX=0.0, sY=0.0, sSqX=0.0, sSqY=0.0; 00181 for (int s =0; s < XY.Len(); s++) { 00182 sX += XY[s].Val1; sY += XY[s].Val2; 00183 sXY += XY[s].Val1 * XY[s].Val2; 00184 sSqX += TMath::Sqr(XY[s].Val1); 00185 sSqY += TMath::Sqr(XY[s].Val2); 00186 } 00187 R2 = TMath::Sqr(N*sXY - sX*sY) / ((N*sSqX - sX*sX) * (N*sSqY - sY*sY)); } 00188 if (1.1 < R2 || -1.1 > R2) R2 = 0.0; 00189 if (_isnan(A) || ! _finite(A)) A = 0.0; 00190 if (_isnan(B) || ! _finite(B)) B = 0.0; 00191 } 00192 00193 void TSpecFunc::PowerFit(const TVec<TFltPr>& XY, double& A, double& B, 00194 double& SigA, double& SigB, double& Chi2, double& R2) { 00195 // y = a x^b :: SigA (SigB): A's uncertainty; Chi2: std dev on all points 00196 // log fit 00197 double AA, BB; 00198 TFltPrV LogXY(XY.Len(), 0); 00199 for (int s = 0; s < XY.Len(); s++) { 00200 LogXY.Add(TFltPr(log((double)XY[s].Val1), log((double)XY[s].Val2))); 00201 } 00202 TSpecFunc::LinearFit(LogXY, AA, BB, SigA, SigB, Chi2, R2); 00203 A = exp(AA); B = BB; 00204 if (_isnan(AA) || ! _finite(AA)) A = 0.0; 00205 if (_isnan(BB) || ! _finite(BB)) B = 0.0; 00206 } 00207 00208 void TSpecFunc::LogFit(const TVec<TFltPr>& XY, double& A, double& B, 00209 double& SigA, double& SigB, double& Chi2, double& R2) { 00210 // Y = A + B*log(X) 00211 TFltPrV LogXY(XY.Len(), 0); 00212 for (int s = 0; s < XY.Len(); s++) { 00213 LogXY.Add(TFltPr(log((double)XY[s].Val1), XY[s].Val2)); 00214 } 00215 TSpecFunc::LinearFit(LogXY, A, B, SigA, SigB, Chi2, R2); 00216 } 00217 00218 void TSpecFunc::ExpFit(const TVec<TFltPr>& XY, double& A, double& B, 00219 double& SigA, double& SigB, double& Chi2, double& R2) { 00220 // Y = A * exp(B*X) 00221 TFltPrV XLogY(XY.Len(), 0); 00222 double AA, BB; 00223 for (int s = 0; s < XY.Len(); s++) { 00224 XLogY.Add(TFltPr(XY[s].Val1, log((double)XY[s].Val2))); 00225 } 00226 TSpecFunc::LinearFit(XLogY, AA, BB, SigA, SigB, Chi2, R2); 00227 A = exp(AA); 00228 B = BB; 00229 } 00230 00231 double TSpecFunc::Entropy(const TIntV& ValV) { 00232 TFltV NewValV(ValV.Len()); 00233 for (int i = 0; i < ValV.Len(); i++) { NewValV[i] = ValV[i]; } 00234 return Entropy(NewValV); 00235 } 00236 00237 // Entropy of a distribution: ValV[i] contains the number of events i 00238 double TSpecFunc::Entropy(const TFltV& ValV) { 00239 double Sum=0, Ent=0; 00240 for (int i = 0; i < ValV.Len(); i++) { 00241 const double& Val = ValV[i]; 00242 if (Val > 0.0) { Ent -= Val * log(Val); Sum += Val; } 00243 } 00244 if (Sum > 0.0) { 00245 Ent /= Sum; 00246 Ent += log(Sum); 00247 Ent /= TMath::LogOf2; 00248 } else return 1.0; 00249 return Ent; 00250 } 00251 00252 void TSpecFunc::EntropyFracDim(const TIntV& ValV, TFltV& EntropyV) { 00253 TFltV NewValV(ValV.Len()); 00254 for (int i = 0; i < ValV.Len(); i++) { 00255 IAssert(ValV[i]==1 || ValV[i] == 0); 00256 NewValV[i] = ValV[i]; 00257 } 00258 EntropyFracDim(NewValV, EntropyV); 00259 } 00260 00261 // Entropy fractal dimension. Input is a vector {0,1}^n. 00262 // Where 0 means the event did not occur, and 1 means it occured. 00263 // Works exactly as Mengzi Wang's code. 00264 void TSpecFunc::EntropyFracDim(const TFltV& ValV, TFltV& EntropyV) { 00265 TFltV ValV1, ValV2; 00266 int Pow2 = 1; 00267 while (2*Pow2 <= ValV.Len()) { Pow2 *= 2; } 00268 ValV1.Gen(Pow2); 00269 for (int i = 0; i < Pow2; i++) { ValV1[i] = ValV[i]; 00270 IAssert(ValV[i]==1.0 || ValV[i] == 0.0); } 00271 EntropyV.Clr(); 00272 EntropyV.Add(Entropy(ValV1)); // 2^Pow2 windows 00273 while (ValV1.Len() > 2) { 00274 ValV2.Gen(ValV1.Len() / 2); 00275 for (int i = 0; i < ValV1.Len(); i++) { 00276 ValV2[i/2] += ValV1[i]; 00277 } 00278 EntropyV.Add(Entropy(ValV2)); 00279 ValV1.MoveFrom(ValV2); 00280 } 00281 EntropyV.Reverse(); 00282 } 00283 00284 // solves for p: B = p * log2(p) + (1-p) * log2(1-p) 00285 double TSpecFunc::EntropyBias(const double& B){ 00286 static TFltFltH BToP; 00287 if (BToP.Empty()) { 00288 for (double p = 0.5; p < 1.0; p +=0.0001) { 00289 double H = p * log(p) + (1.0-p) * log(1.0 - p); 00290 H = -H / log(2.0); 00291 BToP.AddDat(TMath::Round(H, 3), p); 00292 } 00293 } 00294 if (BToP.IsKey(TMath::Round(B, 3))) { return BToP.GetDat(TMath::Round(B, 3)); } 00295 else { return -1.0; } 00296 } 00297 00298 // MLE of the power-law coefficient 00299 double TSpecFunc::GetPowerCoef(const TFltV& XValV, double MinX) { 00300 for (int i = 0; MinX <= 0.0 && i < XValV.Len(); i++) { 00301 MinX = XValV[i]; } 00302 IAssert(MinX > 0.0); 00303 double LnSum=0.0; 00304 for (int i = 0; i < XValV.Len(); i++) { 00305 if (XValV[i].Val < MinX) continue; 00306 LnSum += log(XValV[i] / MinX); 00307 } 00308 return 1.0 + double(XValV.Len()) / LnSum; 00309 } 00310 00311 double TSpecFunc::GetPowerCoef(const TFltPrV& XValCntV, double MinX) { 00312 for (int i = 0; MinX <= 0.0 && i < XValCntV.Len(); i++) { 00313 MinX = XValCntV[i].Val1; } 00314 IAssert(MinX > 0.0); 00315 double NSamples=0.0, LnSum=0.0; 00316 for (int i = 0; i < XValCntV.Len(); i++) { 00317 if (XValCntV[i].Val1() < MinX) continue; 00318 LnSum += XValCntV[i].Val2 * log(XValCntV[i].Val1 / MinX); 00319 NSamples += XValCntV[i].Val2; 00320 } 00321 return 1.0 + NSamples / LnSum; 00322 } 00323 00325 // Statistical-Moments 00326 TMom::TMom(const TFltV& _ValV): 00327 //WgtV(_ValV.Len(), 0), ValV(_ValV.Len(), 0), 00328 ValWgtV(_ValV.Len(), 0), 00329 SumW(), ValSumW(), 00330 UsableP(false), UnusableVal(-1), 00331 Mn(), Mx(), 00332 Mean(), Vari(), SDev(), SErr(), 00333 Median(), Quart1(), Quart3(), 00334 DecileV(), PercentileV(){ 00335 for (int ValN=0; ValN<_ValV.Len(); ValN++){Add(_ValV[ValN], 1);} 00336 Def(); 00337 } 00338 00339 void TMom::Def(){ 00340 IAssert(!DefP); DefP=true; 00341 UsableP=(SumW>0)&&(ValWgtV.Len()>0); 00342 if (UsableP){ 00343 // Mn, Mx 00344 Mn=ValWgtV[0].Val1; 00345 Mx=ValWgtV[0].Val1; 00346 // Mean, Variance (Mn, Mx), Standard-Error 00347 Mean=ValSumW/SumW; 00348 Vari=0; 00349 if (ValWgtV.Len()>1){ 00350 for (int ValN=0; ValN<ValWgtV.Len(); ValN++){ 00351 const double Val=ValWgtV[ValN].Val1; 00352 Vari+=ValWgtV[ValN].Val2*TMath::Sqr(Val-Mean); 00353 if (Val<Mn){Mn=Val;} 00354 if (Val>Mx){Mx=Val;} 00355 } 00356 Vari=Vari/SumW; 00357 SErr=sqrt(Vari/(ValWgtV.Len()*(ValWgtV.Len()-1))); 00358 } 00359 // Standard-Deviation 00360 SDev=sqrt(double(Vari)); 00361 // Median 00362 ValWgtV.Sort(); 00363 double CurSumW = 0; 00364 for (int ValN=0; ValN<ValWgtV.Len(); ValN++){ 00365 CurSumW += ValWgtV[ValN].Val2; 00366 if (CurSumW > 0.5*SumW) { 00367 Median = ValWgtV[ValN].Val1; break; } 00368 else if (CurSumW == 0.5*SumW) { 00369 Median = 0.5 * (ValWgtV[ValN].Val1+ValWgtV[ValN+1].Val1); break; } 00370 } 00371 // Quartile-1 and Quartile-3 00372 Quart1=Quart3=TFlt::Mn; 00373 CurSumW = 0; 00374 for (int ValN=0; ValN<ValWgtV.Len(); ValN++){ 00375 CurSumW += ValWgtV[ValN].Val2; 00376 if (Quart1==TFlt::Mn) { 00377 if (CurSumW > 0.25*SumW) { Quart1 = ValWgtV[ValN].Val1; } 00378 //else if (CurSumW == 0.25*SumW) { Quart1 = 0.5 * (ValWgtV[ValN].Val1+ValWgtV[ValN+1].Val1); } 00379 } 00380 if (Quart3==TFlt::Mn) { 00381 if (CurSumW > 0.75*SumW) { Quart3 = ValWgtV[ValN].Val1; } 00382 //else if (CurSumW == 0.75*SumW) { Quart3 = 0.5 * (ValWgtV[ValN].Val1+ValWgtV[ValN+1].Val1); } 00383 } 00384 } 00385 // Deciles & Percentiles 00386 CurSumW = 0; 00387 int DecileN = 1, PercentileN = 1; 00388 DecileV.Gen(11); PercentileV.Gen(101); 00389 DecileV[0]=Mn; DecileV[10]=Mx; 00390 PercentileV[0]=Mn; PercentileV[100]=Mx; 00391 for (int ValN=0; ValN<ValWgtV.Len(); ValN++){ 00392 CurSumW += ValWgtV[ValN].Val2; 00393 if (CurSumW > SumW*DecileN*0.1) { 00394 DecileV[DecileN] = ValWgtV[ValN].Val1; DecileN++; } 00395 if (CurSumW > SumW*PercentileN*0.01) { 00396 PercentileV[PercentileN] = ValWgtV[ValN].Val1; PercentileN++; } 00397 } 00398 } 00399 ValWgtV.Clr(); 00400 } 00401 00402 00403 00404 double TMom::GetByNm(const TStr& MomNm) const { 00405 if (MomNm=="Mean"){return GetMean();} 00406 else if (MomNm=="Vari"){return GetVari();} 00407 else if (MomNm=="SDev"){return GetSDev();} 00408 else if (MomNm=="SErr"){return GetSErr();} 00409 else if (MomNm=="Median"){return GetMedian();} 00410 else if (MomNm=="Quart1"){return GetQuart1();} 00411 else if (MomNm=="Quart3"){return GetQuart3();} 00412 else if (MomNm=="Decile0"){return GetDecile(0);} 00413 else if (MomNm=="Decile1"){return GetDecile(1);} 00414 else if (MomNm=="Decile2"){return GetDecile(2);} 00415 else if (MomNm=="Decile3"){return GetDecile(3);} 00416 else if (MomNm=="Decile4"){return GetDecile(4);} 00417 else if (MomNm=="Decile5"){return GetDecile(5);} 00418 else if (MomNm=="Decile6"){return GetDecile(6);} 00419 else if (MomNm=="Decile7"){return GetDecile(7);} 00420 else if (MomNm=="Decile8"){return GetDecile(8);} 00421 else if (MomNm=="Decile9"){return GetDecile(9);} 00422 else if (MomNm=="Decile10"){return GetDecile(10);} 00423 else {Fail; return 0;} 00424 } 00425 00426 TStr TMom::GetStrByNm(const TStr& MomNm, char* FmtStr) const { 00427 if (IsUsable()){ 00428 if (FmtStr==NULL){ 00429 return TFlt::GetStr(GetByNm(MomNm)); 00430 } else { 00431 return TFlt::GetStr(GetByNm(MomNm), FmtStr); 00432 } 00433 } else { 00434 return "X"; 00435 } 00436 } 00437 00438 TStr TMom::GetStr( 00439 const char& SepCh, const char& DelimCh, 00440 const bool& DecileP, const bool& PercentileP, const TStr& FmtStr) const { 00441 TChA ChA; 00442 if (IsUsable()){ 00443 ChA+="["; ChA+=SepCh; 00444 ChA+="Vals"; ChA+=DelimCh; ChA+=TInt::GetStr(GetVals()); ChA+=SepCh; 00445 ChA+="Min"; ChA+=DelimCh; ChA+=TFlt::GetStr(GetMn(), FmtStr.CStr()); ChA+=SepCh; 00446 ChA+="Max"; ChA+=DelimCh; ChA+=TFlt::GetStr(GetMx(), FmtStr.CStr()); ChA+=SepCh; 00447 ChA+="Mean"; ChA+=DelimCh; ChA+=TFlt::GetStr(GetMean(), FmtStr.CStr()); ChA+=SepCh; 00448 //ChA+="Vari"; ChA+=DelimCh; ChA+=TFlt::GetStr(GetVari(), FmtStr.CStr()); ChA+=SepCh; 00449 ChA+="SDev"; ChA+=DelimCh; ChA+=TFlt::GetStr(GetSDev(), FmtStr.CStr()); ChA+=SepCh; 00450 //ChA+="SErr"; ChA+=DelimCh; ChA+=TFlt::GetStr(GetSErr(), FmtStr.CStr()); ChA+=SepCh; 00451 ChA+="Quart1"; ChA+=DelimCh; ChA+=TFlt::GetStr(GetQuart1(), FmtStr.CStr()); ChA+=SepCh; 00452 ChA+="Median"; ChA+=DelimCh; ChA+=TFlt::GetStr(GetMedian(), FmtStr.CStr()); ChA+=SepCh; 00453 ChA+="Quart3"; ChA+=DelimCh; ChA+=TFlt::GetStr(GetQuart3(), FmtStr.CStr()); ChA+=SepCh; 00454 if (DecileP){ 00455 for (int DecileN=0; DecileN<=10; DecileN++){ 00456 ChA+="Dec"; ChA+=TInt::GetStr(DecileN); 00457 ChA+=DelimCh; ChA+=TFlt::GetStr(GetDecile(DecileN), FmtStr.CStr()); 00458 ChA+=SepCh; 00459 } 00460 } 00461 if (PercentileP){ 00462 for (int PercentileN=0; PercentileN<=100; PercentileN++){ 00463 ChA+="Per"; ChA+=TInt::GetStr(PercentileN); 00464 ChA+=DelimCh; ChA+=TFlt::GetStr(GetPercentile(PercentileN), FmtStr.CStr()); 00465 ChA+=SepCh; 00466 } 00467 } 00468 ChA+="]"; 00469 } else { 00470 ChA="[Unusable]"; 00471 } 00472 return ChA; 00473 } 00474 00475 TStr TMom::GetNmVStr(const TStr& VarPfx, 00476 const char& SepCh, const bool& DecileP, const bool& PercentileP){ 00477 TChA ChA; 00478 ChA+=VarPfx; ChA+="Vals"; ChA+=SepCh; 00479 ChA+=VarPfx; ChA+="Min"; ChA+=SepCh; 00480 ChA+=VarPfx; ChA+="Max"; ChA+=SepCh; 00481 ChA+=VarPfx; ChA+="Mean"; ChA+=SepCh; 00482 //ChA+=VarPfx; ChA+="Vari"; ChA+=SepCh; 00483 ChA+=VarPfx; ChA+="SDev"; ChA+=SepCh; 00484 //ChA+=VarPfx; ChA+="SErr"; ChA+=SepCh; 00485 ChA+=VarPfx; ChA+="Quart1"; ChA+=SepCh; 00486 ChA+=VarPfx; ChA+="Median"; ChA+=SepCh; 00487 ChA+=VarPfx; ChA+="Quart3"; 00488 if (DecileP){ 00489 ChA+=SepCh; 00490 for (int DecileN=0; DecileN<=10; DecileN++){ 00491 ChA+=VarPfx; ChA+="Dec"; ChA+=TInt::GetStr(DecileN); 00492 if (DecileN<10){ChA+=SepCh;} 00493 } 00494 } 00495 if (PercentileP){ 00496 ChA+=SepCh; 00497 for (int PercentileN=0; PercentileN<=100; PercentileN++){ 00498 ChA+=VarPfx; ChA+="Per"; ChA+=TInt::GetStr(PercentileN); 00499 if (PercentileN<100){ChA+=SepCh;} 00500 } 00501 } 00502 return ChA; 00503 } 00504 00505 TStr TMom::GetValVStr( 00506 const char& SepCh, const bool& DecileP, const bool& PercentileP) const { 00507 TChA ChA; 00508 if (IsUsable()){ 00509 ChA+=TInt::GetStr(GetVals()); ChA+=SepCh; 00510 ChA+=TFlt::GetStr(GetMn()); ChA+=SepCh; 00511 ChA+=TFlt::GetStr(GetMx()); ChA+=SepCh; 00512 ChA+=TFlt::GetStr(GetMean()); ChA+=SepCh; 00513 //ChA+=TFlt::GetStr(GetVari()); ChA+=SepCh; 00514 ChA+=TFlt::GetStr(GetSDev()); ChA+=SepCh; 00515 //ChA+=TFlt::GetStr(GetSErr()); ChA+=SepCh; 00516 ChA+=TFlt::GetStr(GetQuart1()); ChA+=SepCh; 00517 ChA+=TFlt::GetStr(GetMedian()); ChA+=SepCh; 00518 ChA+=TFlt::GetStr(GetQuart3()); ChA+=SepCh; 00519 if (DecileP){ 00520 for (int DecileN=0; DecileN<=10; DecileN++){ 00521 ChA+=TFlt::GetStr(GetDecile(DecileN)); ChA+=SepCh; 00522 } 00523 } 00524 if (PercentileP){ 00525 for (int PercentileN=0; PercentileN<=100; PercentileN++){ 00526 ChA+=TFlt::GetStr(GetPercentile(PercentileN)); ChA+=SepCh; 00527 } 00528 } 00529 } else { 00530 int Vals=8; 00531 if (DecileP){Vals+=11;} 00532 if (PercentileP){Vals+=101;} 00533 for (int ValN=0; ValN<Vals; ValN++){ 00534 ChA="[Unusable]"; 00535 if (ValN<Vals-1){ChA+=SepCh;} 00536 } 00537 } 00538 return ChA; 00539 } 00540 00542 // Correlation 00543 TCorr::TCorr(const TFltV& ValV1, const TFltV& ValV2): 00544 ValVLen(ValV1.Len()), CorrCf(), CorrCfPrb(), FisherZ(){ 00545 static const double TINY=1.0e-20; 00546 IAssert(ValV1.Len()==ValV2.Len()); 00547 00548 // calculate the means 00549 double MeanVal1=0; double MeanVal2=0; 00550 {for (int ValN=0; ValN<ValVLen; ValN++){ 00551 MeanVal1+=ValV1[ValN]; MeanVal2+=ValV2[ValN];}} 00552 MeanVal1/=ValVLen; MeanVal2/=ValVLen; 00553 00554 // calculate correlation coefficient 00555 double yt, xt; 00556 double syy=0.0; double sxy=0.0; double sxx=0.0; 00557 {for (int ValN=0; ValN<ValVLen; ValN++){ 00558 xt=ValV1[ValN]-MeanVal1; 00559 yt=ValV2[ValN]-MeanVal2; 00560 sxx+=xt*xt; 00561 syy+=yt*yt; 00562 sxy+=xt*yt; 00563 }} 00564 if (sxx*syy==0){ 00565 CorrCf=0; //** not in numerical recipes - check why (pojavi se, ko so same nicle) 00566 } else { 00567 CorrCf=sxy/sqrt(sxx*syy); 00568 } 00569 // calculate correlation coefficient significance level 00570 double df=ValVLen-2; 00571 double t=CorrCf*sqrt(df/((1.0-CorrCf+TINY)*(1.0+CorrCf+TINY))); 00572 CorrCfPrb=TSpecFunc::BetaI(0.5*df,0.5,df/(df+t*t)); 00573 // calculate Fisher's Z transformation 00574 FisherZ=0.5*log((1.0+(CorrCf)+TINY)/(1.0-(CorrCf)+TINY)); 00575 } 00576 00578 // Statistical Tests 00579 void TStatTest::AveVar(const TFltV& ValV, double& Ave, double& Var){ 00580 Ave=0; 00581 for (int ValN=0; ValN<ValV.Len(); ValN++){ 00582 Ave+=ValV[ValN];} 00583 Ave/=ValV.Len(); 00584 Var=0; 00585 double ep=0; 00586 for (int ValN=0; ValN<ValV.Len(); ValN++){ 00587 double s=ValV[ValN]-Ave; 00588 ep+=s; 00589 Var+=s*s; 00590 } 00591 Var=(Var-ep*ep/ValV.Len())/(ValV.Len()-1); 00592 } 00593 00594 double TStatTest::KsProb(const double& Alam) { 00595 const double EPS1 = 0.001; 00596 const double EPS2 = 1.0e-8; 00597 double a2 = -2.0*Alam*Alam, fac = 2.0, sum = 0.0, term, termbf = 0.0; 00598 for (int j=1; j <= 100; j++) { 00599 term = fac*exp(a2*j*j); 00600 sum += term; 00601 if (fabs(term) <= EPS1*termbf || fabs(term) <= EPS2*sum) 00602 return sum; 00603 fac = -fac; 00604 termbf = fabs(term); 00605 } 00606 return 1.0; 00607 } 00608 00609 void TStatTest::ChiSquareOne( 00610 const TFltV& ObservedBinV, const TFltV& ExpectedBinV, 00611 double& ChiSquareVal, double& SignificancePrb){ 00612 IAssert(ObservedBinV.Len()==ExpectedBinV.Len()); 00613 int Bins=ObservedBinV.Len(); 00614 int Constraints=0; 00615 int DegreesOfFreedom=Bins-Constraints; 00616 ChiSquareVal=0.0; 00617 for (int BinN=0; BinN<Bins; BinN++){ 00618 IAssert(ExpectedBinV[BinN]>0); 00619 double BinDiff=ObservedBinV[BinN]-ExpectedBinV[BinN]; 00620 ChiSquareVal+=BinDiff*BinDiff/ExpectedBinV[BinN]; 00621 } 00622 SignificancePrb= 00623 TSpecFunc::GammaQ(0.5*(DegreesOfFreedom), 0.5*(ChiSquareVal)); 00624 } 00625 00626 void TStatTest::ChiSquareTwo( 00627 const TFltV& ObservedBin1V, const TFltV& ObservedBin2V, 00628 double& ChiSquareVal, double& SignificancePrb){ 00629 IAssert(ObservedBin1V.Len()==ObservedBin1V.Len()); 00630 int Bins=ObservedBin1V.Len(); 00631 int Constraints=0; 00632 int DegreesOfFreedom=Bins-Constraints; 00633 ChiSquareVal=0.0; 00634 for (int BinN=0; BinN<Bins; BinN++){ 00635 if ((ObservedBin1V[BinN]==0.0) && (ObservedBin2V[BinN]==0.0)){ 00636 DegreesOfFreedom--; 00637 } else { 00638 double BinDiff=ObservedBin1V[BinN]-ObservedBin2V[BinN]; 00639 ChiSquareVal+=BinDiff*BinDiff/(ObservedBin1V[BinN]+ObservedBin2V[BinN]); 00640 } 00641 } 00642 SignificancePrb= 00643 TSpecFunc::GammaQ(0.5*(DegreesOfFreedom),0.5*(ChiSquareVal)); 00644 } 00645 00646 void TStatTest::TTest( 00647 const TFltV& ValV1, const TFltV& ValV2, double& TTestVal, double& TTestPrb){ 00648 /*double Ave1; double Var1; 00649 AveVar(ValV1, Ave1, Var1); 00650 double Ave2; double Var2; 00651 AveVar(ValV2, Ave2, Var2);*/ 00652 00653 PMom Val1Mom=TMom::New(ValV1); 00654 PMom Val2Mom=TMom::New(ValV2); 00655 double ave1=Val1Mom->GetMean(); 00656 double ave2=Val2Mom->GetMean(); 00657 double var1=Val1Mom->GetVari(); 00658 double var2=Val2Mom->GetVari(); 00659 int n1=ValV1.Len(); 00660 int n2=ValV2.Len(); 00661 00662 TTestVal=(ave1-ave2)/sqrt(var1/n1+var2/n2); 00663 double df=TMath::Sqr(var1/n1+var2/n2)/(TMath::Sqr(var1/n1)/(n1-1)+TMath::Sqr(var2/n2)/(n2-1)); 00664 TTestPrb=TSpecFunc::BetaI(0.5*df, 0.5, df/(df+TMath::Sqr(TTestVal))); 00665 } 00666 00667 void TStatTest::KsTest(const TFltV& ValV1, const TFltV& ValV2, double& DStat, double& PVal) { 00668 IAssert(ValV1.IsSorted() && ValV2.IsSorted()); 00669 int i1=0, i2=0; 00670 double CumSum1=0.0, CumSum2=0.0, Cdf1=0.0, Cdf2=0.0; 00671 const double N1 = ValV1.Len(); 00672 const double N2 = ValV2.Len(); 00673 if (! (N1 > 0.0 && N2 > 0.0)) { DStat = 1.0; PVal = 0.0; return; } 00674 DStat=0.0; PVal=0.0; 00675 while (i1 < ValV1.Len() && i2 < ValV2.Len()) { 00676 const double X1 = ValV1[i1]; 00677 const double X2 = ValV2[i2]; 00678 if (X1 <= X2) { 00679 CumSum1 += 1; 00680 Cdf1 = (CumSum1 / N1); 00681 i1++; 00682 } 00683 if (X2 <= X1) { 00684 CumSum2 += 1; 00685 Cdf2 = (CumSum2 / N2); 00686 i2++; 00687 } 00688 DStat = TMath::Mx(DStat, fabs(Cdf1 - Cdf2)); 00689 } 00690 const double En = sqrt( N1*N2 / (N1+N2)); 00691 PVal = TStatTest::KsProb((En+0.12+0.11/En)*DStat); 00692 } 00693 00694 void TStatTest::KsTest(const TFltPrV& ValCntV1, const TFltPrV& ValCntV2, double& DStat, double& PVal) { 00695 IAssert(ValCntV1.IsSorted() && ValCntV2.IsSorted()); 00696 int i1=0, i2=0; 00697 double N1=0.0, N2=0.0, CumSum1=0.0, CumSum2=0.0, Cdf1=0.0, Cdf2=0.0; 00698 DStat=0.0; PVal=0.0; 00699 for (int i = 0; i < ValCntV1.Len(); i++) N1 += ValCntV1[i].Val2; 00700 for (int i = 0; i < ValCntV2.Len(); i++) N2 += ValCntV2[i].Val2; 00701 if (! (N1 > 0.0 && N2 > 0.0)) { DStat = 1.0; PVal = 0.0; return; } 00702 00703 while (i1 < ValCntV1.Len() && i2 < ValCntV2.Len()) { 00704 const double X1 = ValCntV1[i1].Val1; 00705 const double X2 = ValCntV2[i2].Val1; 00706 if (X1 <= X2) { 00707 CumSum1 += ValCntV1[i1].Val2; 00708 Cdf1 = (CumSum1 / N1); 00709 i1++; 00710 } 00711 if (X2 <= X1) { 00712 CumSum2 += ValCntV2[i2].Val2; 00713 Cdf2 = (CumSum2 / N2); 00714 i2++; 00715 } 00716 DStat = TMath::Mx(DStat, fabs(Cdf1 - Cdf2)); 00717 } 00718 const double En = sqrt( N1*N2 / (N1+N2)); 00719 PVal = TStatTest::KsProb((En+0.12+0.11/En)*DStat); 00720 } 00721 00723 // Combinations 00724 bool TComb::GetNext(){ 00725 if (ItemV.Len()==0){ 00726 ItemV.Gen(Order, Order); 00727 for (int OrderN=0; OrderN<Order; OrderN++){ 00728 ItemV[OrderN]=OrderN;} 00729 return true; 00730 } else { 00731 if (ItemV.Last()==Items-1){ 00732 int OrderN=Order-1; 00733 while ((OrderN>=0)&&(ItemV[OrderN]==Items-(Order-OrderN-1)-1)){OrderN--;} 00734 if (OrderN<0){ 00735 return false; 00736 } else { 00737 ItemV[OrderN]++; 00738 for (int SubOrderN=OrderN+1; SubOrderN<Order; SubOrderN++){ 00739 ItemV[SubOrderN]=ItemV[SubOrderN-1]+1;} 00740 CombN++; return true; 00741 } 00742 } else { 00743 ItemV.Last()++; CombN++; return true; 00744 } 00745 } 00746 } 00747 00748 int TComb::GetCombs() const { 00749 int LCombs=1; int HCombs=1; 00750 for (int OrderN=0; OrderN<Order; OrderN++){ 00751 LCombs*=OrderN+1; HCombs*=Items-OrderN;} 00752 int Combs=HCombs/LCombs; 00753 return Combs; 00754 } 00755 00756 void TComb::Wr(){ 00757 printf("%d:[", GetCombN()); 00758 for (int OrderN=0; OrderN<Order; OrderN++){ 00759 if (OrderN>0){printf(" ");} 00760 printf("%d", ItemV[OrderN]()); 00761 } 00762 printf("]\n"); 00763 } 00764 00766 // Linear-Regression 00767 PLinReg TLinReg::New(const TFltVV& _XVV, const TFltV& _YV, const TFltV& _SigV){ 00768 PLinReg LinReg=PLinReg(new TLinReg()); 00769 LinReg->XVV=_XVV; 00770 LinReg->YV=_YV; 00771 if (_SigV.Empty()){ 00772 LinReg->SigV.Gen(LinReg->YV.Len()); 00773 LinReg->SigV.PutAll(1); 00774 } else { 00775 LinReg->SigV=_SigV; 00776 } 00777 LinReg->Recs=LinReg->XVV.GetXDim(); 00778 LinReg->Vars=LinReg->XVV.GetYDim(); 00779 IAssert(LinReg->Recs>0); 00780 IAssert(LinReg->Vars>0); 00781 IAssert(LinReg->YV.Len()==LinReg->Recs); 00782 IAssert(LinReg->SigV.Len()==LinReg->Recs); 00783 LinReg->CovarVV.Gen(LinReg->Vars+1, LinReg->Vars+1); 00784 LinReg->CfV.Gen(LinReg->Vars+1); 00785 LinReg->NR_lfit(); 00786 return LinReg; 00787 } 00788 00789 void TLinReg::NR_covsrt( 00790 TFltVV& CovarVV, const int& Vars, const TIntV& ia, const int& mfit){ 00791 for (int i=mfit+1; i<=Vars; i++){ 00792 for (int j=1; j<=i; j++){ 00793 CovarVV.At(i, j)=0; CovarVV.At(j, i)=0.0;} 00794 } 00795 int k=mfit; 00796 for (int j=Vars; j>=1; j--){ 00797 if (ia[j]!=0){ 00798 for (int i=1; i<=Vars; i++){Swap(CovarVV.At(i, k), CovarVV.At(i, j));} 00799 {for (int i=1; i<=Vars; i++){Swap(CovarVV.At(k, i), CovarVV.At(j, i));}} 00800 k--; 00801 } 00802 } 00803 } 00804 00805 void TLinReg::NR_gaussj(TFltVV& a, const int& n, TFltVV& b, const int& m){ 00806 int i, icol, irow=0, j, k, l, ll; 00807 double big, dum, pivinv; 00808 00809 TIntV indxc(n+1); 00810 TIntV indxr(n+1); 00811 TIntV ipiv(n+1); 00812 for (j=1; j<=n; j++){ipiv[j]=0;} 00813 for (i=1; i<=n; i++){ 00814 big=0.0; 00815 for (j=1; j<=n; j++){ 00816 if (ipiv[j]!=1){ 00817 for (k=1; k<=n; k++){ 00818 if (ipiv[k]==0){ 00819 if (fabs(double(a.At(j, k))) >= big){ 00820 big=fabs(double(a.At(j, k))); 00821 irow=j; 00822 icol=k; 00823 } 00824 } else 00825 if (ipiv[k]>1){ 00826 TExcept::Throw("Singular Matrix(1) in Gauss");} 00827 } 00828 } 00829 } 00830 ipiv[icol]++; 00831 if (irow != icol){ 00832 for (l=1; l<=n; l++){Swap(a.At(irow, l), a.At(icol, l));} 00833 for (l=1; l<=m; l++){Swap(b.At(irow, l), b.At(icol, l));} 00834 } 00835 indxr[i]=irow; 00836 indxc[i]=icol; 00837 if (a.At(icol, icol)==0.0){ 00838 TExcept::Throw("Singular Matrix(1) in Gauss");} 00839 pivinv=1.0/a.At(icol, icol); 00840 a.At(icol, icol)=1.0; 00841 for (l=1; l<=n; l++){a.At(icol, l)=a.At(icol, l)*pivinv;} 00842 for (l=1; l<=m; l++){b.At(icol, l)=b.At(icol, l)*pivinv;} 00843 for (ll=1; ll<=n; ll++){ 00844 if (ll != icol){ 00845 dum=a.At(ll, icol); 00846 a.At(ll, icol)=0.0; 00847 for (l=1;l<=n;l++){a.At(ll, l)-=a.At(icol, l)*dum;} 00848 for (l=1;l<=m;l++){b.At(ll, l)-=b.At(icol, l)*dum;} 00849 } 00850 } 00851 } 00852 for (l=n; l>=1; l--){ 00853 if (indxr[l]!=indxc[l]){ 00854 for (k=1; k<=n; k++){ 00855 Swap(a.At(k, indxr[l]), a.At(k, indxc[l]));} 00856 } 00857 } 00858 } 00859 00860 void TLinReg::NR_lfit(){ 00861 int i,j,k,l,m,mfit=0; 00862 double ym,wt,sum,sig2i; 00863 00864 TIntV ia(Vars+1); for (i=1; i<=Vars; i++){ia[i]=1;} 00865 TFltVV beta(Vars+1, 1+1); 00866 TFltV afunc(Vars+1); 00867 for (j=1;j<=Vars;j++){ 00868 if (ia[j]!=0){mfit++;}} 00869 if (mfit==0){TExcept::Throw("No parameters to be fitted in LFit");} 00870 for (j=1; j<=mfit; j++){ 00871 for (k=1; k<=mfit; k++){CovarVV.At(j, k)=0.0;} 00872 beta.At(j, 1)=0.0; 00873 } 00874 for (i=1; i<=Recs; i++){ 00875 GetXV(i, afunc); // funcs(XVV[i],afunc,Vars); 00876 ym=GetY(i); 00877 if (mfit<Vars){ 00878 for (j=1;j<=Vars;j++){ 00879 if (ia[j]==0){ym-=CfV[j]*afunc[j];}} 00880 } 00881 sig2i=1.0/TMath::Sqr(GetSig(i)); 00882 for (j=0, l=1; l<=Vars; l++){ 00883 if (ia[l]!=0){ 00884 wt=afunc[l]*sig2i; 00885 for (j++, k=0, m=1; m<=l; m++){ 00886 if (ia[m]!=0){CovarVV.At(j, ++k)+=wt*afunc[m];} 00887 } 00888 beta.At(j, 1)+=ym*wt; 00889 } 00890 } 00891 } 00892 for (j=2; j<=mfit; j++){ 00893 for (k=1; k<j; k++){CovarVV.At(k, j)=CovarVV.At(j, k);} 00894 } 00895 NR_gaussj(CovarVV, mfit, beta, 1); 00896 for (j=0, l=1; l<=Vars; l++){ 00897 if (ia[l]!=0){CfV[l]=beta.At(++j, 1);} 00898 } 00899 ChiSq=0.0; 00900 for (i=1; i<=Recs; i++){ 00901 GetXV(i, afunc); // funcs(XVV[i],afunc,Vars); 00902 for (sum=0.0, j=1; j<=Vars; j++){sum+=CfV[j]*afunc[j];} 00903 ChiSq+=TMath::Sqr((GetY(i)-sum)/GetSig(i)); 00904 } 00905 NR_covsrt(CovarVV, Vars, ia, mfit); 00906 } 00907 00908 void TLinReg::Wr() const { 00909 printf("\n%11s %21s\n","parameter","uncertainty"); 00910 for (int i=0; i<Vars;i++){ 00911 printf(" a[%1d] = %8.6f %12.6f\n", 00912 i+1, GetCf(i), GetCfUncer(i)); 00913 } 00914 printf("chi-squared = %12f\n", GetChiSq()); 00915 00916 printf("full covariance matrix\n"); 00917 {for (int i=0;i<Vars;i++){ 00918 for (int j=0;j<Vars;j++){ 00919 printf("%12f", GetCovar(i, j));} 00920 printf("\n"); 00921 }} 00922 } 00923 00925 // Singular-Value-Decomposition 00926 PSvd TSvd::New(const TFltVV& _XVV, const TFltV& _YV, const TFltV& _SigV){ 00927 PSvd Svd=PSvd(new TSvd()); 00928 Svd->XVV=_XVV; 00929 Svd->YV=_YV; 00930 if (_SigV.Empty()){ 00931 Svd->SigV.Gen(Svd->YV.Len()); 00932 Svd->SigV.PutAll(1); 00933 } else { 00934 Svd->SigV=_SigV; 00935 } 00936 Svd->Recs=Svd->XVV.GetXDim(); 00937 Svd->Vars=Svd->XVV.GetYDim(); 00938 IAssert(Svd->Recs>0); 00939 IAssert(Svd->Vars>0); 00940 IAssert(Svd->YV.Len()==Svd->Recs); 00941 IAssert(Svd->SigV.Len()==Svd->Recs); 00942 Svd->CovarVV.Gen(Svd->Vars+1, Svd->Vars+1); 00943 Svd->CfV.Gen(Svd->Vars+1); 00944 Svd->NR_svdfit(); 00945 return Svd; 00946 } 00947 00948 double TSvd::NR_pythag(double a, double b){ 00949 double absa,absb; 00950 absa=fabs(a); 00951 absb=fabs(b); 00952 if (absa > absb){ 00953 return absa*sqrt(1.0+TMath::Sqr(absb/absa)); 00954 } else { 00955 return (absb == 0.0 ? 0.0 : absb*sqrt(1.0+TMath::Sqr(absa/absb))); 00956 } 00957 } 00958 00959 void TSvd::NR_svdcmp(TFltVV& a, int m, int n, TFltV& w, TFltVV& v){ 00960 int flag,i,its,j,jj,k,l=0,nm; 00961 double anorm,c,f,g,h,s,scale,x,y,z; 00962 00963 TFltV rv1(n+1); 00964 g=scale=anorm=0.0; 00965 for (i=1;i<=n;i++) { 00966 l=i+1; 00967 rv1[i]=scale*g; 00968 g=s=scale=0.0; 00969 if (i <= m) { 00970 for (k=i;k<=m;k++) scale += fabs(double(a.At(k,i))); 00971 if (scale) { 00972 for (k=i;k<=m;k++) { 00973 a.At(k,i) /= scale; 00974 s += a.At(k,i)*a.At(k,i); 00975 } 00976 f=a.At(i,i); 00977 g = -NR_SIGN(sqrt(s),f); 00978 h=f*g-s; 00979 a.At(i,i)=f-g; 00980 for (j=l;j<=n;j++) { 00981 for (s=0.0,k=i;k<=m;k++) s += a.At(k,i)*a(k,j); 00982 f=s/h; 00983 for (k=i;k<=m;k++) a.At(k,j) += f*a.At(k,i); 00984 } 00985 for (k=i;k<=m;k++) a.At(k,i) *= scale; 00986 } 00987 } 00988 w[i]=scale *g; 00989 g=s=scale=0.0; 00990 if (i <= m && i != n) { 00991 for (k=l;k<=n;k++) scale += fabs(double(a.At(i,k))); 00992 if (scale) { 00993 for (k=l;k<=n;k++) { 00994 a.At(i,k) /= scale; 00995 s += a.At(i,k)*a.At(i,k); 00996 } 00997 f=a.At(i,l); 00998 g = -NR_SIGN(sqrt(s),f); 00999 h=f*g-s; 01000 a.At(i,l)=f-g; 01001 for (k=l;k<=n;k++) rv1[k]=a.At(i,k)/h; 01002 for (j=l;j<=m;j++) { 01003 for (s=0.0,k=l;k<=n;k++) s += a.At(j,k)*a.At(i,k); 01004 for (k=l;k<=n;k++) a.At(j,k) += s*rv1[k]; 01005 } 01006 for (k=l;k<=n;k++) a.At(i,k) *= scale; 01007 } 01008 } 01009 anorm=NR_FMAX(anorm,(fabs(double(w[i]))+fabs(double(rv1[i])))); 01010 } 01011 for (i=n;i>=1;i--) { 01012 if (i < n) { 01013 if (g) { 01014 for (j=l;j<=n;j++) 01015 v.At(j,i)=(a.At(i,j)/a.At(i,l))/g; 01016 for (j=l;j<=n;j++) { 01017 for (s=0.0,k=l;k<=n;k++) s += a.At(i,k)*v.At(k,j); 01018 for (k=l;k<=n;k++) v.At(k,j) += s*v.At(k,i); 01019 } 01020 } 01021 for (j=l;j<=n;j++) v.At(i,j)=v.At(j,i)=0.0; 01022 } 01023 v.At(i,i)=1.0; 01024 g=rv1[i]; 01025 l=i; 01026 } 01027 for (i=NR_IMIN(m,n);i>=1;i--) { 01028 l=i+1; 01029 g=w[i]; 01030 for (j=l;j<=n;j++) a.At(i,j)=0.0; 01031 if (g) { 01032 g=1.0/g; 01033 for (j=l;j<=n;j++) { 01034 for (s=0.0,k=l;k<=m;k++) s += a.At(k,i)*a.At(k,j); 01035 f=(s/a.At(i,i))*g; 01036 for (k=i;k<=m;k++) a.At(k,j) += f*a.At(k,i); 01037 } 01038 for (j=i;j<=m;j++) a.At(j,i) *= g; 01039 } else for (j=i;j<=m;j++) a.At(j,i)=0.0; 01040 a.At(i,i)++; 01041 } 01042 for (k=n;k>=1;k--) { 01043 for (its=1;its<=30;its++) { 01044 flag=1; 01045 for (l=k;l>=1;l--) { 01046 nm=l-1; 01047 if ((double)(fabs(double(rv1[l])+anorm)) == anorm) { 01048 flag=0; 01049 break; 01050 } 01051 if ((double)(fabs(double(w[nm]))+anorm) == anorm) break; 01052 } 01053 if (flag) { 01054 c=0.0; 01055 s=1.0; 01056 for (i=l;i<=k;i++) { 01057 f=s*rv1[i]; 01058 rv1[i]=c*rv1[i]; 01059 if ((double)(fabs(f)+anorm) == anorm) break; 01060 g=w[i]; 01061 h=NR_pythag(f,g); 01062 w[i]=h; 01063 h=1.0/h; 01064 c=g*h; 01065 s = -f*h; 01066 for (j=1;j<=m;j++) { 01067 y=a.At(j,nm); 01068 z=a.At(j,i); 01069 a.At(j,nm)=y*c+z*s; 01070 a.At(j,i)=z*c-y*s; 01071 } 01072 } 01073 } 01074 z=w[k]; 01075 if (l == k) { 01076 if (z < 0.0) { 01077 w[k] = -z; 01078 for (j=1;j<=n;j++) v.At(j,k) = -v.At(j,k); 01079 } 01080 break; 01081 } 01082 if (its==30){ 01083 TExcept::Throw("no convergence in 30 svdcmp iterations");} 01084 x=w[l]; 01085 nm=k-1; 01086 y=w[nm]; 01087 g=rv1[nm]; 01088 h=rv1[k]; 01089 f=((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y); 01090 g=NR_pythag(f,1.0); 01091 f=((x-z)*(x+z)+h*((y/(f+NR_SIGN(g,f)))-h))/x; 01092 c=s=1.0; 01093 for (j=l;j<=nm;j++) { 01094 i=j+1; 01095 g=rv1[i]; 01096 y=w[i]; 01097 h=s*g; 01098 g=c*g; 01099 z=NR_pythag(f,h); 01100 rv1[j]=z; 01101 c=f/z; 01102 s=h/z; 01103 f=x*c+g*s; 01104 g = g*c-x*s; 01105 h=y*s; 01106 y *= c; 01107 for (jj=1;jj<=n;jj++) { 01108 x=v.At(jj,j); 01109 z=v.At(jj,i); 01110 v.At(jj,j)=x*c+z*s; 01111 v.At(jj,i)=z*c-x*s; 01112 } 01113 z=NR_pythag(f,h); 01114 w[j]=z; 01115 if (z) { 01116 z=1.0/z; 01117 c=f*z; 01118 s=h*z; 01119 } 01120 f=c*g+s*y; 01121 x=c*y-s*g; 01122 for (jj=1;jj<=m;jj++) { 01123 y=a.At(jj,j); 01124 z=a.At(jj,i); 01125 a.At(jj,j)=y*c+z*s; 01126 a.At(jj,i)=z*c-y*s; 01127 } 01128 } 01129 rv1[l]=0.0; 01130 rv1[k]=f; 01131 w[k]=x; 01132 } 01133 } 01134 } 01135 01136 void TSvd::NR_svbksb( 01137 TFltVV& u, TFltV& w, TFltVV& v, int m, int n, TFltV& b, TFltV& x){ 01138 int jj,j,i; 01139 double s; 01140 01141 TFltV tmp(n+1); 01142 for (j=1;j<=n;j++) { 01143 s=0.0; 01144 if (w[j]) { 01145 for (i=1;i<=m;i++) s += u.At(i,j)*b[i]; 01146 s /= w[j]; 01147 } 01148 tmp[j]=s; 01149 } 01150 for (j=1;j<=n;j++) { 01151 s=0.0; 01152 for (jj=1;jj<=n;jj++) s += v.At(j,jj)*tmp[jj]; 01153 x[j]=s; 01154 } 01155 } 01156 01157 void TSvd::NR_svdvar(TFltVV& v, int ma, TFltV& w, TFltVV& cvm){ 01158 int k,j,i; 01159 double sum; 01160 01161 TFltV wti(ma+1); 01162 for (i=1;i<=ma;i++) { 01163 wti[i]=0.0; 01164 if (w[i]) wti[i]=1.0/(w[i]*w[i]); 01165 } 01166 for (i=1;i<=ma;i++) { 01167 for (j=1;j<=i;j++) { 01168 for (sum=0.0,k=1;k<=ma;k++) sum += v.At(i,k)*v.At(j,k)*wti[k]; 01169 cvm.At(j,i)=cvm.At(i,j)=sum; 01170 } 01171 } 01172 } 01173 01174 void TSvd::NR_svdfit(){ 01175 int j,i; 01176 double wmax,tmp,thresh,sum; 01177 double TOL=1.0e-5; 01178 01179 TFltVV u(Recs+1, Vars+1); 01180 TFltVV v(Vars+1, Vars+1); 01181 TFltV w(Vars+1); 01182 TFltV b(Recs+1); 01183 TFltV afunc(Vars+1); 01184 for (i=1;i<=Recs;i++) { 01185 GetXV(i, afunc); // (*funcs)(x[i],afunc,Vars); 01186 tmp=1.0/GetSig(i); 01187 for (j=1;j<=Vars;j++){u.At(i,j)=afunc[j]*tmp;} 01188 b[i]=GetY(i)*tmp; 01189 } 01190 NR_svdcmp(u,Recs,Vars,w,v); 01191 wmax=0.0; 01192 for (j=1;j<=Vars;j++){ 01193 if (w[j] > wmax){wmax=w[j];}} 01194 thresh=TOL*wmax; 01195 for (j=1;j<=Vars;j++){ 01196 if (double(w[j])<thresh){w[j]=0.0;}} 01197 NR_svbksb(u,w,v,Recs,Vars,b,CfV); 01198 ChiSq=0.0; 01199 for (i=1;i<=Recs;i++) { 01200 GetXV(i, afunc); // (*funcs)(x[i],afunc,Vars); 01201 for (sum=0.0,j=1;j<=Vars;j++){sum += CfV[j]*afunc[j];} 01202 ChiSq += (tmp=(GetY(i)-sum)/GetSig(i),tmp*tmp); 01203 } 01204 // covariance matrix calculation 01205 CovarVV.Gen(Vars+1, Vars+1); 01206 NR_svdvar(v, Vars, w, CovarVV); 01207 } 01208 01209 void TSvd::GetCfV(TFltV& _CfV){ 01210 _CfV=CfV; _CfV.Del(0); 01211 } 01212 01213 void TSvd::GetCfUncerV(TFltV& CfUncerV){ 01214 CfUncerV.Gen(Vars); 01215 for (int VarN=0; VarN<Vars; VarN++){ 01216 CfUncerV[VarN]=GetCfUncer(VarN); 01217 } 01218 } 01219 01220 // all vectors (matrices) start with 0 01221 void TSvd::Svd(const TFltVV& InMtx, TFltVV& LSingV, TFltV& SingValV, TFltVV& RSingV) { 01222 //LSingV = InMtx; 01223 LSingV.Gen(InMtx.GetYDim()+1, InMtx.GetYDim()+1); 01224 // create 1 based adjacency matrix 01225 for (int x = 0; x < InMtx.GetXDim(); x++) { 01226 for (int y = 0; y < InMtx.GetYDim(); y++) { 01227 LSingV.At(x+1, y+1) = InMtx.At(x, y); 01228 } 01229 } 01230 RSingV.Gen(InMtx.GetYDim()+1, InMtx.GetYDim()+1); 01231 SingValV.Gen(InMtx.GetYDim()+1); 01232 TSvd::NR_svdcmp(LSingV, InMtx.GetXDim(), InMtx.GetYDim(), SingValV, RSingV); 01233 // 0-th singular value/vector is full of zeros, delete it 01234 SingValV.Del(0); 01235 LSingV.DelX(0); LSingV.DelY(0); 01236 RSingV.DelX(0); RSingV.DelY(0); 01237 } 01238 01239 // InMtx1 is 1-based (0-th row/column are full of zeros) 01240 // returned singular vectors/values are 0 based 01241 void TSvd::Svd1Based(const TFltVV& InMtx1, TFltVV& LSingV, TFltV& SingValV, TFltVV& RSingV) { 01242 LSingV = InMtx1; 01243 SingValV.Gen(InMtx1.GetYDim()); 01244 RSingV.Gen(InMtx1.GetYDim(), InMtx1.GetYDim()); 01245 TSvd::NR_svdcmp(LSingV, InMtx1.GetXDim()-1, InMtx1.GetYDim()-1, SingValV, RSingV); 01246 // 0-th singular value/vector is full of zeros, delete it 01247 SingValV.Del(0); 01248 LSingV.DelX(0); LSingV.DelY(0); 01249 RSingV.DelX(0); RSingV.DelY(0); 01250 } 01251 01252 void TSvd::Wr() const { 01253 printf("\n%11s %21s\n","parameter","uncertainty"); 01254 for (int i=0; i<Vars;i++){ 01255 printf(" a[%1d] = %8.6f %12.6f\n", 01256 i+1, GetCf(i), GetCfUncer(i)); 01257 } 01258 printf("chi-squared = %12f\n", GetChiSq()); 01259 01260 printf("full covariance matrix\n"); 01261 {for (int i=0;i<Vars;i++){ 01262 for (int j=0;j<Vars;j++){ 01263 printf("%12f", GetCovar(i, j));} 01264 printf("\n"); 01265 }} 01266 } 01267 01269 // Histogram 01270 void THist::Add(const double& Val, const bool& OnlyInP) { 01271 // get bucket number 01272 const int BucketN = int(floor((Val - MnVal) / BucketSize)); 01273 if (OnlyInP) { 01274 // value should be inside 01275 EAssert(MnVal <= Val && Val <= MxVal); 01276 BucketV[BucketN]++; 01277 } else { 01278 // value does not need to be inside 01279 if (BucketN < 0) { 01280 BucketV[0]++; 01281 } else if (BucketN < BucketV.Len()) { 01282 BucketV[BucketN]++; 01283 } else { 01284 BucketV.Last()++; 01285 } 01286 } 01287 // for computing percentage 01288 Vals++; 01289 } 01290 01291 void THist::SaveStat(const TStr& ValNm, TSOut& FOut) const { 01292 FOut.PutStrLn("#" + ValNm + ": " + Vals.GetStr()); 01293 const int Buckets = BucketV.Len() - 1; 01294 for (int BucketN = 0; BucketN < Buckets; BucketN++) { 01295 FOut.PutStrLn(TStr::Fmt("%d-%d\t%d", BucketSize*BucketN, 01296 BucketSize*(BucketN+1), BucketV[BucketN]())); 01297 } 01298 if (BucketV.Last() > 0) { 01299 FOut.PutStrLn(TStr::Fmt("%d-\t%d", BucketSize*Buckets, BucketV.Last()())); 01300 } 01301 01302 } 01303