SNAP Library , Developer Reference  2013-01-07 14:03:36
SNAP, a general purpose, high performance system for analysis and manipulation of large networks
 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 }