SNAP Library, User Reference  2012-10-15 15:06:59
SNAP, a general purpose network analysis and graph mining library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
gstat.cpp
Go to the documentation of this file.
00001 
00002 // Sigle Snapshot Graph Statistics
00003 int TGStat::NDiamRuns = 10;
00004 int TGStat::TakeSngVals = 100;
00005 const TFltPrV TGStat::EmptyV = TFltPrV();
00006 
00007 bool TGStat::TCmpByVal::operator () (const TGStat& GS1, const TGStat& GS2) const {
00008   IAssertR(GS1.HasVal(ValCmp) && GS2.HasVal(ValCmp), TStr::Fmt("CmpVal: %d (%s)", 
00009     int(ValCmp), TGStat::GetValStr(ValCmp).CStr()).CStr());
00010   bool Res;
00011   if (ValCmp == gsvTime) { Res = GS1.Time < GS2.Time; }
00012   else { Res = GS1.GetVal(ValCmp) < GS2.GetVal(ValCmp); }
00013   if (SortAsc) { return Res; }
00014   else { return ! Res; }
00015 }
00016 
00017 bool TGStat::TCmpByVal::operator () (const PGStat& GS1, const PGStat& GS2) const {
00018   return operator()(*GS1, *GS2);
00019 }
00020 
00021 TGStat::TGStat(const TSecTm& GraphTm, const TStr& GraphName) :
00022   Time(GraphTm), GraphNm(GraphName), ValStatH(), DistrStatH() {
00023 }
00024 
00025 TGStat::TGStat(const PNGraph& Graph, const TSecTm& GraphTm, TFSet StatFSet, const TStr& GraphName) {
00026   TakeStat(Graph, GraphTm, StatFSet, GraphName);
00027 }
00028 
00029 TGStat::TGStat(const PNEGraph& Graph, const TSecTm& GraphTm, TFSet StatFSet, const TStr& GraphName) {
00030   TakeStat(Graph, GraphTm, StatFSet, GraphName);
00031 }
00032 TGStat::TGStat(const TGStat& GStat) : Time(GStat.Time), GraphNm(GStat.GraphNm),
00033   ValStatH(GStat.ValStatH), DistrStatH(GStat.DistrStatH) {
00034 }
00035 
00036 TGStat::TGStat(TSIn& SIn) : Time(SIn), GraphNm(SIn), ValStatH(SIn), DistrStatH(SIn) { }
00037 
00038 void TGStat::Save(TSOut& SOut) const {
00039   Time.Save(SOut);  GraphNm.Save(SOut);
00040   ValStatH.Save(SOut);  DistrStatH.Save(SOut);
00041 }
00042 
00043 TGStat& TGStat::operator = (const TGStat& GStat) {
00044   if (this != &GStat) {
00045     Time = GStat.Time;
00046     GraphNm = GStat.GraphNm;
00047     ValStatH = GStat.ValStatH;
00048     DistrStatH = GStat.DistrStatH;
00049   }
00050   return *this;
00051 }
00052 
00053 bool TGStat::operator == (const TGStat& GStat) const {
00054   return Time==GStat.Time && ValStatH==GStat.ValStatH && DistrStatH==GStat.DistrStatH;
00055 }
00056 
00057 bool TGStat::operator < (const TGStat& GStat) const {
00058   if (Time<GStat.Time) { return true; }
00059   if (Time>GStat.Time) { return false; }
00060   if (ValStatH.Empty() && ! GStat.ValStatH.Empty()) { return true; }
00061   if (GStat.ValStatH.Empty()) { return false; }
00062   for (int v = gsvTime; v < gsvMx; v++) {
00063     if (! ValStatH.IsKey(v) && ! GStat.ValStatH.IsKey(v)) { continue; }
00064     if (ValStatH.IsKey(v) && ! GStat.ValStatH.IsKey(v)) { return false; }
00065     if (! ValStatH.IsKey(v)) { return true; }
00066     if (ValStatH.GetDat(v) < GStat.ValStatH.GetDat(v)) { return true; }
00067   }
00068   return false;
00069 }
00070 
00071 bool TGStat::HasVal(const TGStatVal& StatVal) const {
00072   if (StatVal == gsvTime) { return Time.IsDef(); }
00073   if (StatVal == gsvWccSize) { return HasVal(gsvWccNodes) && HasVal(gsvNodes); }
00074   return ValStatH.IsKey(int(StatVal));
00075 }
00076 
00077 double TGStat::GetVal(const TGStatVal& StatVal) const {
00078   if (StatVal == gsvTime) { return Time.GetAbsSecs(); }
00079   if (StatVal == gsvWccSize) { return GetVal(gsvWccNodes) / GetVal(gsvNodes); }
00080   if (! ValStatH.IsKey(int(StatVal))) { return -1.0; }
00081   return ValStatH.GetDat(int(StatVal));
00082 }
00083 
00084 void TGStat::SetVal(const TGStatVal& StatVal, const double& Val) {
00085   ValStatH.AddDat(int(StatVal), Val);
00086 }
00087 
00088 const TFltPrV& TGStat::GetDistr(const TGStatDistr& Distr) const {
00089   if (! DistrStatH.IsKey(int(Distr))) { return EmptyV; }
00090   return DistrStatH.GetDat(int(Distr));
00091 }
00092 
00093 void TGStat::SetDistr(const TGStatDistr& Distr, const TFltPrV& FltPrV) {
00094   DistrStatH.AddDat(Distr, FltPrV);
00095 }
00096 
00097 void TGStat::GetDistr(const TGStatDistr& Distr, TFltPrV& FltPrV) const {
00098   FltPrV = GetDistr(Distr);
00099 }
00100 
00101 void TGStat::TakeStat(const PNGraph& Graph, const TSecTm& _Time, TFSet StatFSet, const TStr& GraphName) {
00102   printf("\n===TakeStat:  G(%u, %u)\n", Graph->GetNodes(), Graph->GetEdges());
00103   TExeTm ExeTm, FullTm;
00104   Time = _Time;
00105   GraphNm = GraphName;
00106   if (StatFSet.In(gsvNone)) { return; }
00107   TakeBasicStat(Graph, false);
00108   TakeDiam(Graph, StatFSet, false);
00109   if (StatFSet.In(gsdWcc) || StatFSet.In(gsdWccHops) || StatFSet.In(gsvFullDiam) || StatFSet.In(gsvEffWccDiam)) {
00110     PNGraph WccGraph = TSnap::GetMxWcc(Graph);
00111     TakeBasicStat(WccGraph, true);
00112     TakeDiam(WccGraph, StatFSet, true);
00113   }
00114   // degrees
00115   TakeDegDistr(Graph, StatFSet);
00116   // components
00117   TakeConnComp(Graph, StatFSet);
00118   // spectral
00119   TakeSpectral(Graph, StatFSet, -1);
00120   // clustering coeffient
00121   if (StatFSet.In(gsdClustCf) || StatFSet.In(gsvClustCf)) {
00122     TakeClustCf(Graph); }
00123   if (StatFSet.In(gsdTriadPart)) {
00124     TakeTriadPart(Graph); }
00125   printf("  [%s]\n", FullTm.GetTmStr());
00126 }
00127 
00128 void TGStat::TakeSpectral(const PNGraph& Graph, const int _TakeSngVals) {
00129   TakeSpectral(Graph, TFSet() | gsdSngVal | gsdSngVec, _TakeSngVals);
00130 }
00131 
00132 void TGStat::TakeSpectral(const PNGraph& Graph, TFSet StatFSet, int _TakeSngVals) {
00133   if (_TakeSngVals == -1) { _TakeSngVals = TakeSngVals; }
00134   // singular values, vectors
00135   if (StatFSet.In(gsdSngVal)) {
00136     const int SngVals = TMath::Mn(_TakeSngVals, Graph->GetNodes()/2);
00137     TFltV SngValV1;
00138     TSnap::GetSngVals(Graph, SngVals, SngValV1);
00139     SngValV1.Sort(false);
00140     TFltPrV& SngValV = DistrStatH.AddDat(gsdSngVal);
00141     SngValV.Gen(SngValV1.Len(), 0);
00142     for (int i = 0; i < SngValV1.Len(); i++) {
00143       SngValV.Add(TFltPr(i+1, SngValV1[i]));
00144     }
00145   }
00146   if (StatFSet.In(gsdSngVec)) {
00147     TFltV LeftV, RightV;
00148     TSnap::GetSngVec(Graph, LeftV, RightV);
00149     LeftV.Sort(false);
00150     TFltPrV& SngVec = DistrStatH.AddDat(gsdSngVec);
00151     SngVec.Gen(LeftV.Len(), 0);
00152     for (int i = 0; i < TMath::Mn(Kilo(10), LeftV.Len()/2); i++) {
00153       if (LeftV[i] > 0) { SngVec.Add(TFltPr(i+1, LeftV[i])); }
00154     }
00155   }
00156 }
00157 
00158 void TGStat::Plot(const TGStatDistr& Distr, const TStr& FNmPref, TStr Desc, bool PowerFit) const {
00159   if (Desc.Empty()) Desc = FNmPref.GetUc();
00160   if (! HasDistr(Distr) || Distr==gsdUndef || Distr==gsdMx) { return; }
00161   TPlotInfo Info = GetPlotInfo(Distr);
00162   TGnuPlot GnuPlot(Info.Val1+TStr(".")+FNmPref, TStr::Fmt("%s. G(%d, %d)", Desc.CStr(), GetNodes(),GetEdges()));
00163   GnuPlot.SetXYLabel(Info.Val2, Info.Val3);
00164   GnuPlot.SetScale(Info.Val4);
00165   const int plotId = GnuPlot.AddPlot(GetDistr(Distr), gpwLinesPoints, "");
00166   if (PowerFit) { GnuPlot.AddPwrFit(plotId, gpwLines); }
00167   GnuPlot.SavePng();
00168 }
00169 
00170 void TGStat::Plot(const TFSet& FSet, const TStr& FNmPref, TStr Desc, bool PowerFit) const {
00171   for (int d = gsdUndef; d < gsdMx; d++) {
00172     const TGStatDistr Distr = TGStatDistr(d);
00173     if (! FSet.In(Distr)) { continue; }
00174     Plot(Distr, FNmPref, Desc, PowerFit);
00175   }
00176 }
00177 
00178 void TGStat::PlotAll(const TStr& FNmPref, TStr Desc, bool PowerFit) const {
00179   for (int d = gsdUndef; d < gsdMx; d++) {
00180     const TGStatDistr Distr = TGStatDistr(d);
00181     Plot(Distr, FNmPref, Desc, PowerFit);
00182   }
00183 }
00184 
00185 void TGStat::DumpValStat() {
00186   for (int val = gsvNone; val < gsvMx; val++) {
00187     const TGStatVal Val = TGStatVal(val);
00188     if (! HasVal(Val)) { continue; }
00189     printf("  %s\t%g\n", GetValStr(Val).CStr(), GetVal(Val));
00190   }
00191 }
00192 
00193 void TGStat::AvgGStat(const PGStatVec& GStatVec, const bool& ClipAt1) {
00194   AvgGStat(GStatVec->GetGStatV(), ClipAt1);
00195 }
00196 
00197 void TGStat::AvgGStat(const TGStatV& GStatV, const bool& ClipAt1) {
00198   if (GStatV.Empty()) return;
00199   Time = GStatV[0]->Time;
00200   GraphNm = GStatV[0]->GraphNm;
00201   // values
00202   for (int statVal = 0; statVal > gsvMx; statVal++) {
00203     const TGStatVal GStatVal = TGStatVal(statVal);
00204     TMom Mom;
00205     for (int i = 0; i < GStatV.Len(); i++) {
00206       if (GStatV[i]->HasVal(GStatVal)) {
00207         Mom.Add(GStatV[i]->GetVal(GStatVal)); }
00208     }
00209     Mom.Def();
00210     if (Mom.IsUsable()) {
00211       IAssert(Mom.GetVals() == GStatV.Len()); // all must have the value
00212       SetVal(GStatVal, Mom.GetMean());
00213     }
00214   }
00215   // distributions
00216   for (int distr = gsdUndef; distr < gsdMx; distr++) {
00217     const TGStatDistr GStatDistr = TGStatDistr(distr);
00218     THash<TFlt, TFlt> ValToSumH;
00219     int DistrCnt = 0;
00220     for (int i = 0; i < GStatV.Len(); i++) {
00221       if (GStatV[i]->HasDistr(GStatDistr)) {
00222         const TFltPrV& D = GStatV[i]->GetDistr(GStatDistr);
00223         for (int d = 0; d < D.Len(); d++) {
00224           ValToSumH.AddDat(D[d].Val1) += D[d].Val2; }
00225         DistrCnt++;
00226       }
00227     }
00228     IAssert(DistrCnt==0 || DistrCnt==GStatV.Len()); // all must have distribution
00229     TFltPrV AvgStatV;
00230     ValToSumH.GetKeyDatPrV(AvgStatV);  AvgStatV.Sort();
00231     for (int i = 0; i < AvgStatV.Len(); i++) {
00232       AvgStatV[i].Val2 /= double(DistrCnt);
00233       if (ClipAt1 && AvgStatV[i].Val2 < 1) { AvgStatV[i].Val2 = 1; }
00234     }
00235     SetDistr(GStatDistr, AvgStatV);
00236   }
00237 }
00238 
00239 TStr TGStat::GetDistrStr(const TGStatDistr& Distr) {
00240   switch (Distr) {
00241     case gsdUndef : return TStr("Undef");
00242     case gsdInDeg : return "InDeg";
00243     case gsdOutDeg : return "OutDeg";
00244     case gsdWcc : return "WccDist";
00245     case gsdScc : return "SccDist";
00246     case gsdHops : return "Hops";
00247     case gsdWccHops : return "WccHops";
00248     case gsdSngVal : return "SngVal";
00249     case gsdSngVec : return "SngVec";
00250     case gsdClustCf : return "ClustCf";
00251     case gsdTriadPart : return "TriadPart";
00252     case gsdMx: return TStr("Mx");
00253     default: Fail; return TStr();
00254   };
00255 }
00256 
00257 TStr TGStat::GetValStr(const TGStatVal& Val) {
00258   static TIntStrH ValTyStrH;
00259   if (ValTyStrH.Empty()) {
00260     ValTyStrH.AddDat(gsvNone, "None");
00261     ValTyStrH.AddDat(gsvTime, "Time");
00262     ValTyStrH.AddDat(gsvNodes, "Nodes");
00263     ValTyStrH.AddDat(gsvZeroNodes, "ZeroNodes");
00264     ValTyStrH.AddDat(gsvNonZNodes, "NonZNodes");
00265     ValTyStrH.AddDat(gsvSrcNodes, "SrcNodes");
00266     ValTyStrH.AddDat(gsvDstNodes, "DstNodes");
00267     ValTyStrH.AddDat(gsvEdges, "Edges");
00268     ValTyStrH.AddDat(gsvUniqEdges, "UniqEdges");
00269     ValTyStrH.AddDat(gsvBiDirEdges, "BiDirEdges");
00270     ValTyStrH.AddDat(gsvWccNodes, "WccNodes");
00271     ValTyStrH.AddDat(gsvWccSrcNodes, "WccSrcNodes");
00272     ValTyStrH.AddDat(gsvWccDstNodes, "WccDstNodes");
00273     ValTyStrH.AddDat(gsvWccEdges, "WccEdges");
00274     ValTyStrH.AddDat(gsvWccUniqEdges, "WccUniqEdges");
00275     ValTyStrH.AddDat(gsvWccBiDirEdges, "WccBiDirEdges");
00276     ValTyStrH.AddDat(gsvFullDiam, "FullDiam");
00277     ValTyStrH.AddDat(gsvEffDiam, "EffDiam");
00278     ValTyStrH.AddDat(gsvEffWccDiam, "EffWccDiam");
00279     ValTyStrH.AddDat(gsvFullWccDiam, "FullWccDiam");
00280     ValTyStrH.AddDat(gsvFullDiamDev, "FullDiamDev");
00281     ValTyStrH.AddDat(gsvEffDiamDev, "EffDiamDev");
00282     ValTyStrH.AddDat(gsvEffWccDiamDev, "EffWccDiamDev");
00283     ValTyStrH.AddDat(gsvFullWccDiamDev, "FullWccDiamDev");
00284     ValTyStrH.AddDat(gsvClustCf, "ClustCf");
00285     ValTyStrH.AddDat(gsvOpenTriads, "OpenTr");
00286     ValTyStrH.AddDat(gsvClosedTriads, "ClosedTr");
00287     ValTyStrH.AddDat(gsvWccSize, "WccSize");
00288     ValTyStrH.AddDat(gsvMx, "Mx");
00289   }
00290   IAssert(ValTyStrH.IsKey(int(Val)));
00291   return ValTyStrH.GetDat(int(Val));
00292 }
00293 
00294 TGStat::TPlotInfo TGStat::GetPlotInfo(const TGStatVal& Val) {
00295   //switch (Distr) {
00296     //case gsdUndef : Fail; return TPlotInfo();
00297   Fail;
00298   return TPlotInfo();
00299 }
00300 
00301 TGStat::TPlotInfo TGStat::GetPlotInfo(const TGStatDistr& Distr) {
00302   switch (Distr) {
00303     case gsdUndef : Fail; return TPlotInfo();
00304     case gsdInDeg : return TPlotInfo("inDeg", "In-degree, k", "Count", gpsLog10XY);
00305     case gsdOutDeg : return TPlotInfo("outDeg", "Out-degree, k", "Count", gpsLog10XY);
00306     case gsdWcc : return TPlotInfo("wcc", "WCC size", "Count", gpsLog10XY);
00307     case gsdScc : return TPlotInfo("scc", "SCC size", "Count", gpsLog10XY);
00308     case gsdHops : return TPlotInfo("hop", "Number of hops, h", "Reachable pairs of nodes inside h hops", gpsLog10Y);
00309     case gsdWccHops : return TPlotInfo("wccHop", "Number of hops, h", "Reachable pairs of nodes inside h hops in WCC", gpsLog10Y);
00310     case gsdSngVal : return TPlotInfo("sval", "Rank", "Singular value", gpsLog10XY);
00311     case gsdSngVec : return TPlotInfo("svec", "Rank", "Left singular vector", gpsLog10XY);
00312     case gsdClustCf : return TPlotInfo("ccf", "Degree, k", "Clustering coefficient, <C(k)>", gpsLog10XY);
00313     case gsdTriadPart : return TPlotInfo("triad", "Number of triads adjacent to a node", "Number of such nodes", gpsLog10XY);
00314     case gsdMx : Fail;
00315     default: Fail; return TPlotInfo();
00316   };
00317 }
00318 
00319 TFSet TGStat::NoStat() {
00320   return TFSet() | gsvNone;
00321 }
00322 
00323 TFSet TGStat::BasicStat() {
00324   return TFSet();
00325 }
00326 
00327 TFSet TGStat::DegDStat() {
00328   return TFSet() | gsdInDeg |  gsdOutDeg;
00329 }
00330 
00331 TFSet TGStat::NoDiamStat() {
00332   return TFSet() | gsdInDeg |  gsdOutDeg |  gsdWcc |  gsdScc;
00333 }
00334 
00335 TFSet TGStat::NoDistrStat() {
00336   return TFSet() | gsdHops | gsdWccHops;
00337 }
00338 
00339 TFSet TGStat::NoSvdStat() {
00340   return TFSet() | gsdInDeg |  gsdOutDeg |  gsdWcc |  gsdScc |
00341     gsdHops |  gsdWccHops | gsdClustCf | gsdTriadPart;
00342 }
00343 
00344 TFSet TGStat::AllStat() {
00345   return TFSet() | gsdInDeg |  gsdOutDeg |  gsdWcc |  gsdScc
00346     | gsdHops |  gsdWccHops | gsdClustCf | gsdTriadPart 
00347     | gsdSngVec | gsdSngVal | gsvFullDiam;
00348 }
00349 
00351 // Graph Growth Statistics
00352 uint TGStatVec::MinNodesEdges = 10;
00353 
00354 TGStatVec::TGStatVec(const TTmUnit& _TmUnit) : TmUnit(_TmUnit), StatFSet(), GStatV() {
00355   StatFSet = TGStat::AllStat();
00356 }
00357 
00358 TGStatVec::TGStatVec(const TTmUnit& _TmUnit, const TFSet& TakeGrowthStat) :
00359    TmUnit(_TmUnit), StatFSet(TakeGrowthStat), GStatV() {
00360 }
00361 
00362 TGStatVec::TGStatVec(const TGStatVec& GStat) :
00363   TmUnit(GStat.TmUnit), StatFSet(GStat.StatFSet), GStatV(GStat.GStatV) {
00364 }
00365 
00366 TGStatVec::TGStatVec(TSIn& SIn) : TmUnit((TTmUnit) TInt(SIn).Val), StatFSet(SIn), GStatV(SIn) {
00367 }
00368 
00369 PGStatVec TGStatVec::New(const TTmUnit& _TmUnit) {
00370   return new TGStatVec(_TmUnit);
00371 }
00372 
00373 PGStatVec TGStatVec::New(const TTmUnit& _TmUnit, const TFSet& TakeGrowthStat) {
00374   return new TGStatVec(_TmUnit, TakeGrowthStat);
00375 }
00376 
00377 void TGStatVec::Save(TSOut& SOut) const {
00378   TInt(TmUnit).Save(SOut);
00379   StatFSet.Save(SOut);
00380   GStatV.Save(SOut);
00381 }
00382 
00383 TGStatVec& TGStatVec::operator = (const TGStatVec& GStat) {
00384   if (this != &GStat) {
00385     TmUnit = GStat.TmUnit;
00386     StatFSet = GStat.StatFSet;
00387     GStatV = GStat.GStatV;
00388   }
00389   return *this;
00390 }
00391 
00392 PGStat TGStatVec::Add() {
00393   GStatV.Add(TGStat::New());
00394   return GStatV.Last();
00395 }
00396 
00397 PGStat TGStatVec::Add(const TSecTm& Time, TStr GraphNm) {
00398   GStatV.Add(TGStat::New(Time, GraphNm));
00399   return GStatV.Last();
00400 }
00401 
00402 void TGStatVec::Add(const PNGraph& Graph, const TSecTm& Time, const TStr& GraphNm) {
00403   if (Graph->GetNodes() < (int) TGStatVec::MinNodesEdges) {
00404     printf(" ** TGStatVec::Add: graph too small (%d nodes).SKIP\n", Graph->GetNodes());
00405     return;
00406   }
00407   Add(TGStat::New(Graph, Time, StatFSet, GraphNm));
00408 }
00409 
00410 void TGStatVec::Add(const PNEGraph& Graph, const TSecTm& Time, const TStr& GraphNm) {
00411   if (Graph->GetNodes() < (int) TGStatVec::MinNodesEdges) {
00412     printf(" ** TGStatVec::Add: graph too small (%d nodes).SKIP\n", Graph->GetNodes());
00413     return;
00414   }
00415   Add(TGStat::New(Graph, Time, StatFSet, GraphNm));
00416 }
00417 
00418 void TGStatVec::Sort(const TGStatVal& SortBy, const bool& Asc) {
00419   GStatV.SortCmp(TGStat::TCmpByVal(SortBy, Asc));
00420 }
00421 
00422 void TGStatVec::DelBefore(const TSecTm& Tm) {
00423   TGStatV NewTickV;
00424   for (int i = 0; i < Len(); i++) {
00425     if (At(i)->Time >= Tm) { NewTickV.Add(At(i)); }
00426   }
00427   GStatV.Swap(NewTickV);
00428 }
00429 
00430 void TGStatVec::DelAfter(const TSecTm& Tm) {
00431   TGStatV NewTickV;
00432   for (int i = 0; i < Len(); i++) {
00433     if (At(i)->Time <= Tm) { NewTickV.Add(At(i)); }
00434   }
00435   GStatV.Swap(NewTickV);
00436 }
00437 
00438 void TGStatVec::DelSmallNodes(const int& MinNodes) {
00439   TGStatV NewTickV;
00440   for (int i = 0; i < Len(); i++) {
00441     if (At(i)->GetNodes() >= MinNodes) { NewTickV.Add(At(i)); }
00442   }
00443   GStatV.Swap(NewTickV);
00444 }
00445 
00446 void TGStatVec::GetValV(const TGStatVal& XVal, const TGStatVal& YVal, TFltPrV& ValV) const {
00447   ValV.Gen(Len(), 0);
00448   double x;
00449   for (int t = 0; t < Len(); t++) {
00450     if (XVal == gsvTime) { x = t+1; }
00451     else { x = At(t)->GetVal(XVal); }
00452     ValV.Add(TFltPr(x, At(t)->GetVal(YVal)));
00453   }
00454 }
00455 
00456 PGStat TGStatVec::GetAvgGStat(const bool& ClipAt1) {
00457   PGStat Stat = TGStat::New();
00458   Stat->AvgGStat(GStatV, ClipAt1);
00459   return Stat;
00460 }
00461 
00462 void TGStatVec::Plot(const TGStatVal& XVal, const TGStatVal& YVal, const TStr& OutFNm, TStr& Desc, const TGpScaleTy& Scale,const bool& PowerFit) const {
00463   if (! Last()->HasVal(XVal) || ! Last()->HasVal(YVal)) {
00464     if (! Last()->HasVal(XVal)) { printf("** Does not have %s statistic\n", TGStat::GetValStr(XVal).CStr()); }
00465     if (! Last()->HasVal(YVal)) { printf("** Does not have %s statistic\n", TGStat::GetValStr(YVal).CStr()); }
00466     return;
00467   }
00468   if (Desc.Empty()) { Desc = OutFNm; }
00469   TFltPrV ValV;
00470   TGStatVec::GetValV(XVal, YVal, ValV);
00471   TGnuPlot GP(TStr::Fmt("%s-%s.%s", TGStat::GetValStr(XVal).CStr(), TGStat::GetValStr(YVal).CStr(), OutFNm.CStr()),
00472     TStr::Fmt("%s. %s vs. %s. G(%d,%d)", Desc.CStr(), TGStat::GetValStr(XVal).CStr(), TGStat::GetValStr(YVal).CStr(),
00473     Last()->GetNodes(), Last()->GetEdges()));
00474   GP.SetScale(Scale);
00475   GP.SetXYLabel(TGStat::GetValStr(XVal), TGStat::GetValStr(YVal));
00476   const int Id = GP.AddPlot(ValV, gpwLinesPoints);
00477   if (PowerFit) { GP.AddPwrFit(Id); }
00478   GP.SavePng();
00479 }
00480 
00481 void TGStatVec::PlotAllVsX(const TGStatVal& XVal, const TStr& OutFNm, TStr Desc, const TGpScaleTy& Scale, const bool& PowerFit) const {
00482   const TFSet SkipStat = TFSet() | gsvFullDiamDev | gsvEffDiamDev | gsvEffWccDiamDev | gsvFullWccDiamDev;
00483   for (int stat = gsvNone; stat < gsvMx; stat++) {
00484     const TGStatVal Stat = TGStatVal(stat);
00485     if (SkipStat.In(Stat)) { continue; }
00486     if (Last()->HasVal(Stat) && Last()->HasVal(XVal) && Stat!=XVal) {
00487       Plot(XVal, Stat, OutFNm, Desc, Scale, PowerFit);
00488     }
00489   }
00490 }
00491 
00492 void TGStatVec::ImposeDistr(const TGStatDistr& Distr, const TStr& FNmPref, TStr Desc, const bool& ExpBin, 
00493     const bool& PowerFit, const TGpSeriesTy& PlotWith, const TStr& Style) const {
00494   if (Desc.Empty()) Desc = FNmPref.GetUc();
00495   if (! At(0)->HasDistr(Distr) || Distr==gsdUndef || Distr==gsdMx) { return; }
00496   TGStat::TPlotInfo Info = At(0)->GetPlotInfo(Distr);
00497   TGnuPlot GnuPlot(Info.Val1+TStr(".")+FNmPref, TStr::Fmt("%s. G(%d, %d) --> G(%d, %d)", Desc.CStr(),
00498     At(0)->GetNodes(), At(0)->GetEdges(), Last()->GetNodes(), Last()->GetEdges()));
00499   GnuPlot.SetXYLabel(Info.Val2, Info.Val3);
00500   GnuPlot.SetScale(Info.Val4);
00501   int plotId;
00502   for (int at = 0; at < Len(); at++) {
00503     TStr Legend = At(at)->GetNm();
00504     if (Legend.Empty()) { Legend = At(at)->GetTmStr(); }
00505     if (! ExpBin) { 
00506       plotId = GnuPlot.AddPlot(At(at)->GetDistr(Distr), PlotWith, Legend, Style); }
00507     else { 
00508       TFltPrV ExpBinV; 
00509       TGnuPlot::MakeExpBins(At(at)->GetDistr(Distr), ExpBinV, 2, 0);
00510       plotId = GnuPlot.AddPlot(ExpBinV, PlotWith, Legend, Style);
00511     }
00512     if (PowerFit) { GnuPlot.AddPwrFit(plotId, gpwLines); }
00513   }
00514   GnuPlot.SavePng();
00515 }
00516 
00517 void TGStatVec::SaveTxt(const TStr& FNmPref, const TStr& Desc) const {
00518   FILE *F = fopen(TStr::Fmt("growth.%s.tab", FNmPref.CStr()).CStr(), "wt");
00519   fprintf(F, "# %s\n", Desc.CStr());
00520   fprintf(F, "# %s", TTmInfo::GetTmUnitStr(TmUnit).CStr());
00521   TIntSet StatValSet;
00522   for (int i = 0; i < Len(); i++) {
00523     for (int v = gsvNone; v < gsvMx; v++) {
00524       if (At(i)->HasVal(TGStatVal(v))) { StatValSet.AddKey(v); }
00525     }
00526   }
00527   TIntV StatValV;  StatValSet.GetKeyV(StatValV);  StatValV.Sort();
00528   for (int sv = 0; sv < StatValV.Len(); sv++) {
00529     fprintf(F, "\t%s", TGStat::GetValStr(TGStatVal(StatValV[sv].Val)).CStr()); }
00530   fprintf(F, "Time\n");
00531   for (int i = 0; i < Len(); i++) {
00532     const TGStat& G = *At(i);
00533     for (int sv = 0; sv < StatValV.Len(); sv++) {
00534       fprintf(F, "%g\t", G.GetVal(TGStatVal(StatValV[sv].Val))); }
00535     fprintf(F, "%s\n", G.GetTmStr().CStr());
00536   }
00537   fclose(F);
00538 }