-
Notifications
You must be signed in to change notification settings - Fork 0
/
xmath.h
executable file
·488 lines (439 loc) · 17.2 KB
/
xmath.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
/////////////////////////////////////////////////
// Mathematics-Utilities
class TMath{
public:
static double E;
static double Pi;
static double LogOf2;
static double Inv(const double& x){IAssert(x!=0.0); return (1.0/x);}
static double Sqr(const double& x){return x*x;}
static double Sqrt(const double& x){IAssert(x>0.0); return sqrt(x);}
static double Log2(const double& Val){return log(Val)/LogOf2;}
static double Round(const double& Val){
return (Val>0)?floor(Val+0.5):ceil(Val-0.5);}
static double Round(const double & Val, int Decs){
const double pwr=pow(10.0, Decs); return Round(Val * pwr) / pwr;}
static int Fac(const int& Val){
if (Val<=1){return 1;} else {return Val*Fac(Val-1);}}
static int Choose(const int& N, const int& K){ // binomial coefficient
return Fac(N)/(Fac(K)*Fac(N-K)); }
static uint Pow2(const int& pow){return uint(1u<<pow);}
static double Power(const double& Base, const double& Exponent){
return exp(log(Base)*Exponent);}
template <typename T>
static int Sign(const T& Val){return Val<0?-1:(Val>0?1:0);}
template <class T>
static const T& Mx(const T& LVal, const T& RVal) {
return LVal > RVal ? LVal : RVal;}
template <class T>
static const T& Mn(const T& LVal, const T& RVal){
return LVal < RVal ? LVal : RVal;}
template <class T>
static const T& Mx(const T& Val1, const T& Val2, const T& Val3) {
if (Val1 > Val2) {
if (Val1 > Val3) return Val1;
else return Val3;
} else {
if (Val2 > Val3) return Val2;
else return Val3;
}
}
template <class T>
static const T& Mn(const T& Val1, const T& Val2, const T& Val3) {
if(Val1 < Val2) {
if (Val1 < Val3) return Val1;
else return Val3;
} else {
if (Val2 < Val3) return Val2;
else return Val3;
}
}
template <class T>
static const T& Median(const T& Val1, const T& Val2, const T& Val3) {
if (Val1 < Val2) {
if (Val2 < Val3) return Val2;
else if (Val3 < Val1) return Val1;
else return Val3;
} else {
if (Val1 < Val3) return Val1;
else if (Val3 < Val2) return Val2;
else return Val3;
}
}
template <class T>
static const T& InRange(const T& Val, const T& Mn, const T& Mx) {
IAssert(Mn <= Mx); return Val < Mn ? Mn : (Val > Mx ? Mx : Val);}
template <class T>
static bool IsInRange(const T& Val, const T& Mn, const T& Mx) {
IAssert(Mn <= Mx); return Val >= Mn && Val <= Mx;}
template <class T>
static bool IsInEps(const T& Val, const T& Eps) {
return Val >= -Eps && Val <= Eps;}
};
/////////////////////////////////////////////////
// Special-Functions
class TSpecFunc{
public:
static void GammaPSeries/*gser*/(
double& gamser, const double& a, const double& x, double& gln);
static void GammaQContFrac/*gcf*/(
double& gammcf, const double& a, const double& x, double& gln);
static double GammaQ/*gammq*/(const double& a, const double& x);
static double LnGamma/*gammln*/(const double& xx);
static double BetaCf/*betacf*/(
const double& a, const double& b, const double& x);
static double BetaI(const double& a, const double& b, const double& x);
static void LinearFit( // Y = A + B*X
const TVec<TFltPr>& XY, double& A, double& B,
double& SigA, double& SigB, double& Chi2, double& R2);
static void PowerFit( // Y = A * X^B
const TVec<TFltPr>& XY, double& A, double& B,
double& SigA, double& SigB, double& Chi2, double& R2);
static void LogFit( // Y = A + B*log(X)
const TVec<TFltPr>& XY, double& A, double& B,
double& SigA, double& SigB, double& Chi2, double& R2);
static void ExpFit( // Y = A * exp(B*X)
const TVec<TFltPr>& XY, double& A, double& B,
double& SigA, double& SigB, double& Chi2, double& R2);
public:
static double LnComb(const int& n, const int& k);
public:
static double Entropy(const TIntV& ValV);
static double Entropy(const TFltV& ValV);
static void EntropyFracDim(const TIntV& ValV, TFltV& EntropyV);
static void EntropyFracDim(const TFltV& ValV, TFltV& EntropyV);
public:
static double EntropyBias(const double& B); // solves for p: B = p*log2(p)+(1-p)log2(1-p)
//MLE of the power-law coefficient
static double GetPowerCoef(const TFltV& XValV, double MinX=-1.0); // values (sampled from the distribution)
static double GetPowerCoef(const TFltPrV& XValCntV, double MinX=-1.0); // (value, count) pairs
};
/////////////////////////////////////////////////
// Statistical-Moments
ClassTPV(TMom, PMom, TMomV)//{
private:
TBool DefP;
TFltPrV ValWgtV;
TFlt SumW, ValSumW;
TInt Vals;
TBool UsableP;
TFlt UnusableVal;
TFlt Mn, Mx;
TFlt Mean, Vari, SDev, SErr;
TFlt Median, Quart1, Quart3;
TFltV DecileV; // 0=min 1=1.decile, ..., 9=9.decile, 10=max
TFltV PercentileV; // 0=min 1=1.percentile, ..., 9=9.percentile, 10=max
public:
TMom():
DefP(false), ValWgtV(),
SumW(), ValSumW(), Vals(),
UsableP(false), UnusableVal(-1),
Mn(), Mx(),
Mean(), Vari(), SDev(), SErr(),
Median(), Quart1(), Quart3(),
DecileV(), PercentileV(){}
TMom(const TMom& Mom):
DefP(Mom.DefP), ValWgtV(Mom.ValWgtV),
SumW(Mom.SumW), ValSumW(Mom.ValSumW), Vals(Mom.Vals),
UsableP(Mom.UsableP), UnusableVal(Mom.UnusableVal),
Mn(Mom.Mn), Mx(Mom.Mx),
Mean(Mom.Mean), Vari(Mom.Vari), SDev(Mom.SDev), SErr(Mom.SErr),
Median(Mom.Median), Quart1(Mom.Quart1), Quart3(Mom.Quart3),
DecileV(Mom.DecileV), PercentileV(Mom.PercentileV){}
static PMom New(){return PMom(new TMom());}
static void NewV(TMomV& MomV, const int& Moms){
MomV.Gen(Moms); for (int MomN=0; MomN<Moms; MomN++){MomV[MomN]=New();}}
static void NewVV(TVVec<PMom>& MomVV, const int& XMoms, const int& YMoms){
MomVV.Gen(XMoms, YMoms);
for (int XMomN=0; XMomN<XMoms; XMomN++){
for (int YMomN=0; YMomN<YMoms; YMomN++){
MomVV.At(XMomN, YMomN)=New();}}}
TMom(const TFltV& _ValV);
static PMom New(const TFltV& ValV){
return PMom(new TMom(ValV));}
TMom(TSIn& SIn):
DefP(SIn),
ValWgtV(SIn),
SumW(SIn), ValSumW(SIn), Vals(SIn),
UsableP(SIn), UnusableVal(SIn),
Mn(SIn), Mx(SIn),
Mean(SIn), Vari(SIn), SDev(SIn), SErr(SIn),
Median(SIn), Quart1(SIn), Quart3(SIn),
DecileV(SIn), PercentileV(SIn){}
static PMom Load(TSIn& SIn){return new TMom(SIn);}
void Save(TSOut& SOut) const {
DefP.Save(SOut);
ValWgtV.Save(SOut);
SumW.Save(SOut); ValSumW.Save(SOut); Vals.Save(SOut);
UsableP.Save(SOut); UnusableVal.Save(SOut);
Mn.Save(SOut); Mx.Save(SOut);
Mean.Save(SOut); Vari.Save(SOut); SDev.Save(SOut); SErr.Save(SOut);
Median.Save(SOut); Quart1.Save(SOut); Quart3.Save(SOut);
DecileV.Save(SOut); PercentileV.Save(SOut);}
TMom& operator=(const TMom& Mom){
Assert(!DefP); DefP=Mom.DefP;
ValWgtV=Mom.ValWgtV;
SumW=Mom.SumW; ValSumW=Mom.ValSumW; Vals=Mom.Vals;
UsableP=Mom.UsableP; UnusableVal=Mom.UnusableVal;
Mn=Mom.Mn; Mx=Mom.Mx;
Mean=Mom.Mean; Vari=Mom.Vari; SDev=Mom.SDev; SErr=Mom.SErr;
Median=Mom.Median; Quart1=Mom.Quart1; Quart3=Mom.Quart3;
DecileV=Mom.DecileV; PercentileV=Mom.PercentileV;
return *this;}
bool operator==(const TMom& Mom) const {
return Vals==Mom.Vals;}
bool operator<(const TMom& Mom) const {
return Vals<Mom.Vals;}
// define
void Def();
static void DefV(TMomV& MomV){
for (int MomN=0; MomN<MomV.Len(); MomN++){MomV[MomN]->Def();}}
static void DefVV(TVVec<PMom>& MomVV){
for (int XMomN=0; XMomN<MomVV.GetXDim(); XMomN++){
for (int YMomN=0; YMomN<MomVV.GetYDim(); YMomN++){
MomVV.At(XMomN, YMomN)->Def();}}}
bool IsDef() const {return DefP;}
// values
void Add(const TFlt& Val, const TFlt& Wgt=1){Assert(!DefP);
ValWgtV.Add(TFltPr(Val, Wgt)); SumW+=Wgt; ValSumW+=Wgt*Val; Vals++;}
double GetWgt() const {return SumW;}
int GetVals() const {return Vals;}
TFlt GetVal(const int& ValN) const {IAssert(!IsDef()); return ValWgtV[ValN].Val1;}
//const TFltV& GetValV() const {IAssert(!IsDef()); return ValV;} //J:
// usability
bool IsUsable() const {Assert(DefP); return UsableP;}
static bool IsUsableV(const TMomV& MomV){
for (int MomN=0; MomN<MomV.Len(); MomN++){
if (!MomV[MomN]->IsUsable()){return false;}}
return true;}
static bool IsUsableVV(const TVVec<PMom>& MomVV){
for (int XMomN=0; XMomN<MomVV.GetXDim(); XMomN++){
for (int YMomN=0; YMomN<MomVV.GetYDim(); YMomN++){
if (!MomVV.At(XMomN, YMomN)->IsUsable()){return false;}}}
return true;}
// moments
double GetMn() const {Assert(DefP&&UsableP); return Mn;}
double GetMx() const {Assert(DefP&&UsableP); return Mx;}
double GetExtent() const {Assert(DefP&&UsableP); return Mx-Mn;}
double GetMean() const {Assert(DefP&&UsableP); return Mean;}
double GetVari() const {Assert(DefP&&UsableP); return Vari;}
double GetSDev() const {Assert(DefP&&UsableP); return SDev;}
double GetSErr() const {Assert(DefP&&UsableP); return SErr;}
double GetMedian() const {Assert(DefP&&UsableP); return Median;}
double GetQuart1() const {Assert(DefP&&UsableP); return Quart1;}
double GetQuart3() const {Assert(DefP&&UsableP); return Quart3;}
double GetDecile(const int& DecileN) const {
Assert(DefP&&UsableP); return DecileV[DecileN];}
double GetPercentile(const int& PercentileN) const {
Assert(DefP&&UsableP); return PercentileV[PercentileN];}
double GetByNm(const TStr& MomNm) const;
TStr GetStrByNm(const TStr& MomNm, char* FmtStr=NULL) const;
// strings
TStr GetStr(const char& SepCh=' ', const char& DelimCh=':',
const bool& DecileP=true, const bool& PercentileP=true, const TStr& FmtStr="%g") const;
static TStr GetNmVStr(const TStr& VarPfx,
const char& SepCh='\t', const bool& DecileP=true, const bool& PercentileP=true);
TStr GetValVStr(const char& SepCh='\t', const bool& DecileP=true, const bool& PercentileP=true) const;
};
typedef TVVec<PMom> TMomVV;
typedef THash<TInt, PMom> TIntMomH;
typedef THash<TInt, TMomV> TIntMomVH;
typedef THash<TInt, TMomVV> TIntMomVVH;
/////////////////////////////////////////////////
// Correlation
ClassTP(TCorr, PCorr)//{
private:
int ValVLen;
double CorrCf;
double CorrCfPrb;
double FisherZ;
public:
TCorr(){}
TCorr(const TFltV& ValV1, const TFltV& ValV2);
static PCorr New(const TFltV& ValV1, const TFltV& ValV2){
return PCorr(new TCorr(ValV1, ValV2));}
TCorr(TSIn&){Fail;}
static PCorr Load(TSIn& SIn){return new TCorr(SIn);}
void Save(TSOut&){Fail;}
TCorr& operator=(const TCorr&){Fail; return *this;}
double GetCorrCf() const {return CorrCf;}
double GetCorrCfPrb() const {return CorrCfPrb;}
TStr GetStr() const;
};
/////////////////////////////////////////////////
// Statistical Tests
class TStatTest {
private:
static void AveVar(const TFltV& ValV, double& Ave, double& Var);
static double KsProb(const double& Alam);
public:
static void ChiSquareOne(
const TFltV& ObservedBinV, const TFltV& ExpectedBinV,
double& ChiSquareVal, double& SignificancePrb);
static void ChiSquareTwo(
const TFltV& ObservedBin1V, const TFltV& ObservedBin2V,
double& ChiSquareVal, double& SignificancePrb);
static void TTest(
const TFltV& ValV1, const TFltV& ValV2, double& TTestVal, double& TTestPrb);
// Kolmogorov-Smirnov (are two distributions the same)
static void KsTest(const TFltV& ValV1, const TFltV& ValV2, double& DStat, double& PVal);
static void KsTest(const TFltPrV& ValCntV1, const TFltPrV& ValCntV2, double& DStat, double& PVal);
};
/////////////////////////////////////////////////
// Combinations
ClassTP(TComb, PComb)//{
public:
int Items;
int Order;
int CombN;
TIntV ItemV;
public:
TComb(): Items(-1), Order(-1), CombN(-1), ItemV(){}
TComb(const int& _Items, const int& _Order):
Items(_Items), Order(_Order), CombN(0), ItemV(){
IAssert((Order>0)&&(Order<=Items));}
static PComb New(const int& Items, const int& Order){
return PComb(new TComb(Items, Order));}
~TComb(){}
TComb(TSIn&){Fail;}
static PComb Load(TSIn& SIn){return new TComb(SIn);}
void Save(TSOut&){Fail;}
TComb& operator=(const TComb&){Fail; return *this;}
bool GetNext();
TIntV& GetItemV(){return ItemV;}
int GetCombN() const {return CombN;}
int GetCombs() const;
void Wr();
};
/////////////////////////////////////////////////
// Linear-Regression
ClassTP(TLinReg, PLinReg)//{
public:
TFltVV XVV;
TFltV YV;
TFltV SigV;
int Recs, Vars;
TFltVV CovarVV; // 1 based
TFltV CfV; // 1 based
double ChiSq;
void GetXV(const int RecN, TFltV& VarV) const {
VarV.Gen(Vars+1);
for (int VarN=0; VarN<Vars; VarN++){VarV[VarN+1]=XVV.At(RecN-1, VarN);}
}
double GetY(const int RecN) const {return YV[RecN-1];}
double GetSig(const int RecN) const {return SigV[RecN-1];}
void NR_covsrt(TFltVV& CovarVV, const int& Vars, const TIntV& ia, const int& mfit);
void NR_gaussj(TFltVV& a, const int& n, TFltVV& b, const int& m);
void NR_lfit();
public:
TLinReg(){}
static PLinReg New(
const TFltVV& XVV, const TFltV& YV, const TFltV& SigV=TFltV());
~TLinReg(){}
TLinReg(TSIn&){Fail;}
static PLinReg Load(TSIn& SIn){return new TLinReg(SIn);}
void Save(TSOut&){Fail;}
TLinReg& operator=(const TLinReg&){Fail; return *this;}
int GetRecs() const {return Recs;}
int GetVars() const {return Vars;}
double GetCf(const int& VarN) const {return CfV[VarN+1];}
double GetCfUncer(const int& VarN) const {
return sqrt(double(CovarVV.At(VarN+1, VarN+1)));}
double GetCovar(const int& VarN1, const int& VarN2) const {
return CovarVV.At(VarN1+1, VarN2+1);}
double GetChiSq() const {return ChiSq;}
static double LinInterp(const double& x1, const double& y1,
const double& x2, const double& y2, const double& AtX) _CMPWARN{
if (x1 == x2) return (y1+y2)/2.0;
const double k = (y2 - y1) / (x2 - x1);
return k*(AtX - x1) + y1;
}
void Wr() const;
};
/////////////////////////////////////////////////
// Singular-Value-Decomposition
ClassTP(TSvd, PSvd)//{
public:
TFltVV XVV;
TFltV YV;
TFltV SigV;
int Recs, Vars;
TFltVV CovarVV; // 1 based
TFltV CfV; // 1 based
double ChiSq;
void GetXV(const int RecN, TFltV& VarV) const {
VarV.Gen(Vars+1);
for (int VarN=0; VarN<Vars; VarN++){VarV[VarN+1]=XVV.At(RecN-1, VarN);}
}
double GetY(const int RecN) const {return YV[RecN-1];}
double GetSig(const int RecN) const {return SigV[RecN-1];}
static double NR_SIGN(double a, double b){return b >= 0.0 ? fabs(a) : -fabs(a);}
static double NR_FMAX(double maxarg1, double maxarg2){
return maxarg1 > maxarg2 ? maxarg1 : maxarg2;}
static int NR_IMIN(int iminarg1, int iminarg2){
return iminarg1 < iminarg2 ? iminarg1 : iminarg2;}
static double NR_pythag(double a, double b);
static void NR_svdcmp(TFltVV& a, int m, int n, TFltV& w, TFltVV& v);
void NR_svbksb(
TFltVV& u, TFltV& w, TFltVV& v, int m, int n, TFltV& b, TFltV& x);
void NR_svdvar(TFltVV& v, int ma, TFltV& w, TFltVV& cvm);
void NR_svdfit();
public:
TSvd(){}
static PSvd New(
const TFltVV& XVV, const TFltV& YV, const TFltV& SigV=TFltV());
~TSvd(){}
TSvd(TSIn&){Fail;}
static PSvd Load(TSIn& SIn){return new TSvd(SIn);}
void Save(TSOut&){Fail;}
TSvd& operator=(const TSvd&){Fail; return *this;}
int GetRecs() const {return Recs;}
int GetVars() const {return Vars;}
double GetCf(const int& VarN) const {return CfV[VarN+1];}
double GetCfUncer(const int& VarN) const {
return sqrt(double(CovarVV.At(VarN+1, VarN+1)));}
double GetCovar(const int& VarN1, const int& VarN2) const {
return CovarVV.At(VarN1+1, VarN2+1);}
double GetChiSq() const {return ChiSq;}
void GetCfV(TFltV& _CfV);
void GetCfUncerV(TFltV& CfUncerV);
static void Svd(const TFltVV& InMtx, TFltVV& LSingV, TFltV& SingValV, TFltVV& RSingV);
static void Svd1Based(const TFltVV& InMtx1, TFltVV& LSingV, TFltV& SingValV, TFltVV& RSingV);
void Wr() const;
};
/////////////////////////////////////////////////
// Histogram
class THist {
private:
TInt Vals;
TInt BucketSize;
TIntV BucketV;
public:
THist() { }
THist(const int& _BucketSize, const double& MxVal):
BucketSize(_BucketSize), BucketV(int(ceil(MxVal / _BucketSize) + 1)) { }
void Add(const double& Val) {
const int BucketN = int(floor(Val / BucketSize));
IAssert(BucketN >= 0);
if (BucketN < BucketV.Len()) {
BucketV[BucketN]++;
} else {
BucketV.Last()++;
}
Vals++;
}
void SaveStat(const TStr& ValNm, TSOut& FOut) const {
FOut.PutStrLn("#" + ValNm + ": " + Vals.GetStr());
const int Buckets = BucketV.Len() - 1;
for (int BucketN = 0; BucketN < Buckets; BucketN++) {
FOut.PutStrLn(TStr::Fmt("%d-%d\t%d", BucketSize*BucketN,
BucketSize*(BucketN+1), BucketV[BucketN]()));
}
if (BucketV.Last() > 0) {
FOut.PutStrLn(TStr::Fmt("%d-\t%d", BucketSize*Buckets, BucketV.Last()()));
}
}
void SaveTxt(const TStr& ValNm, const TStr& FNm) const {
TFOut FOut(FNm); SaveStat(ValNm, FOut);
}
};