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
 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   #ifdef GLib_MACOSX
00168   GnuPlot.SaveEps();
00169   #else
00170   GnuPlot.SavePng();
00171   #endif
00172 }
00173 
00174 void TGStat::Plot(const TFSet& FSet, const TStr& FNmPref, TStr Desc, bool PowerFit) const {
00175   for (int d = gsdUndef; d < gsdMx; d++) {
00176     const TGStatDistr Distr = TGStatDistr(d);
00177     if (! FSet.In(Distr)) { continue; }
00178     Plot(Distr, FNmPref, Desc, PowerFit);
00179   }
00180 }
00181 
00182 void TGStat::PlotAll(const TStr& FNmPref, TStr Desc, bool PowerFit) const {
00183   for (int d = gsdUndef; d < gsdMx; d++) {
00184     const TGStatDistr Distr = TGStatDistr(d);
00185     Plot(Distr, FNmPref, Desc, PowerFit);
00186   }
00187 }
00188 
00189 void TGStat::DumpValStat() {
00190   for (int val = gsvNone; val < gsvMx; val++) {
00191     const TGStatVal Val = TGStatVal(val);
00192     if (! HasVal(Val)) { continue; }
00193     printf("  %s\t%g\n", GetValStr(Val).CStr(), GetVal(Val));
00194   }
00195 }
00196 
00197 void TGStat::AvgGStat(const PGStatVec& GStatVec, const bool& ClipAt1) {
00198   AvgGStat(GStatVec->GetGStatV(), ClipAt1);
00199 }
00200 
00201 void TGStat::AvgGStat(const TGStatV& GStatV, const bool& ClipAt1) {
00202   if (GStatV.Empty()) return;
00203   Time = GStatV[0]->Time;
00204   GraphNm = GStatV[0]->GraphNm;
00205   // values
00206   for (int statVal = 0; statVal > gsvMx; statVal++) {
00207     const TGStatVal GStatVal = TGStatVal(statVal);
00208     TMom Mom;
00209     for (int i = 0; i < GStatV.Len(); i++) {
00210       if (GStatV[i]->HasVal(GStatVal)) {
00211         Mom.Add(GStatV[i]->GetVal(GStatVal)); }
00212     }
00213     Mom.Def();
00214     if (Mom.IsUsable()) {
00215       IAssert(Mom.GetVals() == GStatV.Len()); // all must have the value
00216       SetVal(GStatVal, Mom.GetMean());
00217     }
00218   }
00219   // distributions
00220   for (int distr = gsdUndef; distr < gsdMx; distr++) {
00221     const TGStatDistr GStatDistr = TGStatDistr(distr);
00222     THash<TFlt, TFlt> ValToSumH;
00223     int DistrCnt = 0;
00224     for (int i = 0; i < GStatV.Len(); i++) {
00225       if (GStatV[i]->HasDistr(GStatDistr)) {
00226         const TFltPrV& D = GStatV[i]->GetDistr(GStatDistr);
00227         for (int d = 0; d < D.Len(); d++) {
00228           ValToSumH.AddDat(D[d].Val1) += D[d].Val2; }
00229         DistrCnt++;
00230       }
00231     }
00232     IAssert(DistrCnt==0 || DistrCnt==GStatV.Len()); // all must have distribution
00233     TFltPrV AvgStatV;
00234     ValToSumH.GetKeyDatPrV(AvgStatV);  AvgStatV.Sort();
00235     for (int i = 0; i < AvgStatV.Len(); i++) {
00236       AvgStatV[i].Val2 /= double(DistrCnt);
00237       if (ClipAt1 && AvgStatV[i].Val2 < 1) { AvgStatV[i].Val2 = 1; }
00238     }
00239     SetDistr(GStatDistr, AvgStatV);
00240   }
00241 }
00242 
00243 TStr TGStat::GetDistrStr(const TGStatDistr& Distr) {
00244   switch (Distr) {
00245     case gsdUndef : return TStr("Undef");
00246     case gsdInDeg : return "InDeg";
00247     case gsdOutDeg : return "OutDeg";
00248     case gsdWcc : return "WccDist";
00249     case gsdScc : return "SccDist";
00250     case gsdHops : return "Hops";
00251     case gsdWccHops : return "WccHops";
00252     case gsdSngVal : return "SngVal";
00253     case gsdSngVec : return "SngVec";
00254     case gsdClustCf : return "ClustCf";
00255     case gsdTriadPart : return "TriadPart";
00256     case gsdMx: return TStr("Mx");
00257     default: Fail; return TStr();
00258   };
00259 }
00260 
00261 TStr TGStat::GetValStr(const TGStatVal& Val) {
00262   static TIntStrH ValTyStrH;
00263   if (ValTyStrH.Empty()) {
00264     ValTyStrH.AddDat(gsvNone, "None");
00265     ValTyStrH.AddDat(gsvTime, "Time");
00266     ValTyStrH.AddDat(gsvNodes, "Nodes");
00267     ValTyStrH.AddDat(gsvZeroNodes, "ZeroNodes");
00268     ValTyStrH.AddDat(gsvNonZNodes, "NonZNodes");
00269     ValTyStrH.AddDat(gsvSrcNodes, "SrcNodes");
00270     ValTyStrH.AddDat(gsvDstNodes, "DstNodes");
00271     ValTyStrH.AddDat(gsvEdges, "Edges");
00272     ValTyStrH.AddDat(gsvUniqEdges, "UniqEdges");
00273     ValTyStrH.AddDat(gsvBiDirEdges, "BiDirEdges");
00274     ValTyStrH.AddDat(gsvWccNodes, "WccNodes");
00275     ValTyStrH.AddDat(gsvWccSrcNodes, "WccSrcNodes");
00276     ValTyStrH.AddDat(gsvWccDstNodes, "WccDstNodes");
00277     ValTyStrH.AddDat(gsvWccEdges, "WccEdges");
00278     ValTyStrH.AddDat(gsvWccUniqEdges, "WccUniqEdges");
00279     ValTyStrH.AddDat(gsvWccBiDirEdges, "WccBiDirEdges");
00280     ValTyStrH.AddDat(gsvFullDiam, "FullDiam");
00281     ValTyStrH.AddDat(gsvEffDiam, "EffDiam");
00282     ValTyStrH.AddDat(gsvEffWccDiam, "EffWccDiam");
00283     ValTyStrH.AddDat(gsvFullWccDiam, "FullWccDiam");
00284     ValTyStrH.AddDat(gsvFullDiamDev, "FullDiamDev");
00285     ValTyStrH.AddDat(gsvEffDiamDev, "EffDiamDev");
00286     ValTyStrH.AddDat(gsvEffWccDiamDev, "EffWccDiamDev");
00287     ValTyStrH.AddDat(gsvFullWccDiamDev, "FullWccDiamDev");
00288     ValTyStrH.AddDat(gsvClustCf, "ClustCf");
00289     ValTyStrH.AddDat(gsvOpenTriads, "OpenTr");
00290     ValTyStrH.AddDat(gsvClosedTriads, "ClosedTr");
00291     ValTyStrH.AddDat(gsvWccSize, "WccSize");
00292     ValTyStrH.AddDat(gsvMx, "Mx");
00293   }
00294   IAssert(ValTyStrH.IsKey(int(Val)));
00295   return ValTyStrH.GetDat(int(Val));
00296 }
00297 
00298 TGStat::TPlotInfo TGStat::GetPlotInfo(const TGStatVal& Val) {
00299   //switch (Distr) {
00300     //case gsdUndef : Fail; return TPlotInfo();
00301   Fail;
00302   return TPlotInfo();
00303 }
00304 
00305 TGStat::TPlotInfo TGStat::GetPlotInfo(const TGStatDistr& Distr) {
00306   switch (Distr) {
00307     case gsdUndef : Fail; return TPlotInfo();
00308     case gsdInDeg : return TPlotInfo("inDeg", "In-degree, k", "Count", gpsLog10XY);
00309     case gsdOutDeg : return TPlotInfo("outDeg", "Out-degree, k", "Count", gpsLog10XY);
00310     case gsdWcc : return TPlotInfo("wcc", "WCC size", "Count", gpsLog10XY);
00311     case gsdScc : return TPlotInfo("scc", "SCC size", "Count", gpsLog10XY);
00312     case gsdHops : return TPlotInfo("hop", "Number of hops, h", "Reachable pairs of nodes inside h hops", gpsLog10Y);
00313     case gsdWccHops : return TPlotInfo("wccHop", "Number of hops, h", "Reachable pairs of nodes inside h hops in WCC", gpsLog10Y);
00314     case gsdSngVal : return TPlotInfo("sval", "Rank", "Singular value", gpsLog10XY);
00315     case gsdSngVec : return TPlotInfo("svec", "Rank", "Left singular vector", gpsLog10XY);
00316     case gsdClustCf : return TPlotInfo("ccf", "Degree, k", "Clustering coefficient, <C(k)>", gpsLog10XY);
00317     case gsdTriadPart : return TPlotInfo("triad", "Number of triads adjacent to a node", "Number of such nodes", gpsLog10XY);
00318     case gsdMx : Fail;
00319     default: Fail; return TPlotInfo();
00320   };
00321 }
00322 
00323 TFSet TGStat::NoStat() {
00324   return TFSet() | gsvNone;
00325 }
00326 
00327 TFSet TGStat::BasicStat() {
00328   return TFSet();
00329 }
00330 
00331 TFSet TGStat::DegDStat() {
00332   return TFSet() | gsdInDeg |  gsdOutDeg;
00333 }
00334 
00335 TFSet TGStat::NoDiamStat() {
00336   return TFSet() | gsdInDeg |  gsdOutDeg |  gsdWcc |  gsdScc;
00337 }
00338 
00339 TFSet TGStat::NoDistrStat() {
00340   return TFSet() | gsdHops | gsdWccHops;
00341 }
00342 
00343 TFSet TGStat::NoSvdStat() {
00344   return TFSet() | gsdInDeg |  gsdOutDeg |  gsdWcc |  gsdScc |
00345     gsdHops |  gsdWccHops | gsdClustCf | gsdTriadPart;
00346 }
00347 
00348 TFSet TGStat::AllStat() {
00349   return TFSet() | gsdInDeg |  gsdOutDeg |  gsdWcc |  gsdScc
00350     | gsdHops |  gsdWccHops | gsdClustCf | gsdTriadPart 
00351     | gsdSngVec | gsdSngVal | gsvFullDiam;
00352 }
00353 
00355 // Graph Growth Statistics
00356 uint TGStatVec::MinNodesEdges = 10;
00357 
00358 TGStatVec::TGStatVec(const TTmUnit& _TmUnit) : TmUnit(_TmUnit), StatFSet(), GStatV() {
00359   StatFSet = TGStat::AllStat();
00360 }
00361 
00362 TGStatVec::TGStatVec(const TTmUnit& _TmUnit, const TFSet& TakeGrowthStat) :
00363    TmUnit(_TmUnit), StatFSet(TakeGrowthStat), GStatV() {
00364 }
00365 
00366 TGStatVec::TGStatVec(const TGStatVec& GStat) :
00367   TmUnit(GStat.TmUnit), StatFSet(GStat.StatFSet), GStatV(GStat.GStatV) {
00368 }
00369 
00370 TGStatVec::TGStatVec(TSIn& SIn) : TmUnit((TTmUnit) TInt(SIn).Val), StatFSet(SIn), GStatV(SIn) {
00371 }
00372 
00373 PGStatVec TGStatVec::New(const TTmUnit& _TmUnit) {
00374   return new TGStatVec(_TmUnit);
00375 }
00376 
00377 PGStatVec TGStatVec::New(const TTmUnit& _TmUnit, const TFSet& TakeGrowthStat) {
00378   return new TGStatVec(_TmUnit, TakeGrowthStat);
00379 }
00380 
00381 void TGStatVec::Save(TSOut& SOut) const {
00382   TInt(TmUnit).Save(SOut);
00383   StatFSet.Save(SOut);
00384   GStatV.Save(SOut);
00385 }
00386 
00387 TGStatVec& TGStatVec::operator = (const TGStatVec& GStat) {
00388   if (this != &GStat) {
00389     TmUnit = GStat.TmUnit;
00390     StatFSet = GStat.StatFSet;
00391     GStatV = GStat.GStatV;
00392   }
00393   return *this;
00394 }
00395 
00396 PGStat TGStatVec::Add() {
00397   GStatV.Add(TGStat::New());
00398   return GStatV.Last();
00399 }
00400 
00401 PGStat TGStatVec::Add(const TSecTm& Time, TStr GraphNm) {
00402   GStatV.Add(TGStat::New(Time, GraphNm));
00403   return GStatV.Last();
00404 }
00405 
00406 void TGStatVec::Add(const PNGraph& Graph, const TSecTm& Time, const TStr& GraphNm) {
00407   if (Graph->GetNodes() < (int) TGStatVec::MinNodesEdges) {
00408     printf(" ** TGStatVec::Add: graph too small (%d nodes).SKIP\n", Graph->GetNodes());
00409     return;
00410   }
00411   Add(TGStat::New(Graph, Time, StatFSet, GraphNm));
00412 }
00413 
00414 void TGStatVec::Add(const PNEGraph& Graph, const TSecTm& Time, const TStr& GraphNm) {
00415   if (Graph->GetNodes() < (int) TGStatVec::MinNodesEdges) {
00416     printf(" ** TGStatVec::Add: graph too small (%d nodes).SKIP\n", Graph->GetNodes());
00417     return;
00418   }
00419   Add(TGStat::New(Graph, Time, StatFSet, GraphNm));
00420 }
00421 
00422 void TGStatVec::Sort(const TGStatVal& SortBy, const bool& Asc) {
00423   GStatV.SortCmp(TGStat::TCmpByVal(SortBy, Asc));
00424 }
00425 
00426 void TGStatVec::DelBefore(const TSecTm& Tm) {
00427   TGStatV NewTickV;
00428   for (int i = 0; i < Len(); i++) {
00429     if (At(i)->Time >= Tm) { NewTickV.Add(At(i)); }
00430   }
00431   GStatV.Swap(NewTickV);
00432 }
00433 
00434 void TGStatVec::DelAfter(const TSecTm& Tm) {
00435   TGStatV NewTickV;
00436   for (int i = 0; i < Len(); i++) {
00437     if (At(i)->Time <= Tm) { NewTickV.Add(At(i)); }
00438   }
00439   GStatV.Swap(NewTickV);
00440 }
00441 
00442 void TGStatVec::DelSmallNodes(const int& MinNodes) {
00443   TGStatV NewTickV;
00444   for (int i = 0; i < Len(); i++) {
00445     if (At(i)->GetNodes() >= MinNodes) { NewTickV.Add(At(i)); }
00446   }
00447   GStatV.Swap(NewTickV);
00448 }
00449 
00450 void TGStatVec::GetValV(const TGStatVal& XVal, const TGStatVal& YVal, TFltPrV& ValV) const {
00451   ValV.Gen(Len(), 0);
00452   double x;
00453   for (int t = 0; t < Len(); t++) {
00454     if (XVal == gsvTime) { x = t+1; }
00455     else { x = At(t)->GetVal(XVal); }
00456     ValV.Add(TFltPr(x, At(t)->GetVal(YVal)));
00457   }
00458 }
00459 
00460 PGStat TGStatVec::GetAvgGStat(const bool& ClipAt1) {
00461   PGStat Stat = TGStat::New();
00462   Stat->AvgGStat(GStatV, ClipAt1);
00463   return Stat;
00464 }
00465 
00466 void TGStatVec::Plot(const TGStatVal& XVal, const TGStatVal& YVal, const TStr& OutFNm, TStr& Desc, const TGpScaleTy& Scale,const bool& PowerFit) const {
00467   if (! Last()->HasVal(XVal) || ! Last()->HasVal(YVal)) {
00468     if (! Last()->HasVal(XVal)) { printf("** Does not have %s statistic\n", TGStat::GetValStr(XVal).CStr()); }
00469     if (! Last()->HasVal(YVal)) { printf("** Does not have %s statistic\n", TGStat::GetValStr(YVal).CStr()); }
00470     return;
00471   }
00472   if (Desc.Empty()) { Desc = OutFNm; }
00473   TFltPrV ValV;
00474   TGStatVec::GetValV(XVal, YVal, ValV);
00475   TGnuPlot GP(TStr::Fmt("%s-%s.%s", TGStat::GetValStr(XVal).CStr(), TGStat::GetValStr(YVal).CStr(), OutFNm.CStr()),
00476     TStr::Fmt("%s. %s vs. %s. G(%d,%d)", Desc.CStr(), TGStat::GetValStr(XVal).CStr(), TGStat::GetValStr(YVal).CStr(),
00477     Last()->GetNodes(), Last()->GetEdges()));
00478   GP.SetScale(Scale);
00479   GP.SetXYLabel(TGStat::GetValStr(XVal), TGStat::GetValStr(YVal));
00480   const int Id = GP.AddPlot(ValV, gpwLinesPoints);
00481   if (PowerFit) { GP.AddPwrFit(Id); }
00482   GP.SavePng();
00483 }
00484 
00485 void TGStatVec::PlotAllVsX(const TGStatVal& XVal, const TStr& OutFNm, TStr Desc, const TGpScaleTy& Scale, const bool& PowerFit) const {
00486   const TFSet SkipStat = TFSet() | gsvFullDiamDev | gsvEffDiamDev | gsvEffWccDiamDev | gsvFullWccDiamDev;
00487   for (int stat = gsvNone; stat < gsvMx; stat++) {
00488     const TGStatVal Stat = TGStatVal(stat);
00489     if (SkipStat.In(Stat)) { continue; }
00490     if (Last()->HasVal(Stat) && Last()->HasVal(XVal) && Stat!=XVal) {
00491       Plot(XVal, Stat, OutFNm, Desc, Scale, PowerFit);
00492     }
00493   }
00494 }
00495 
00496 void TGStatVec::ImposeDistr(const TGStatDistr& Distr, const TStr& FNmPref, TStr Desc, const bool& ExpBin, 
00497     const bool& PowerFit, const TGpSeriesTy& PlotWith, const TStr& Style) const {
00498   if (Desc.Empty()) Desc = FNmPref.GetUc();
00499   if (! At(0)->HasDistr(Distr) || Distr==gsdUndef || Distr==gsdMx) { return; }
00500   TGStat::TPlotInfo Info = At(0)->GetPlotInfo(Distr);
00501   TGnuPlot GnuPlot(Info.Val1+TStr(".")+FNmPref, TStr::Fmt("%s. G(%d, %d) --> G(%d, %d)", Desc.CStr(),
00502     At(0)->GetNodes(), At(0)->GetEdges(), Last()->GetNodes(), Last()->GetEdges()));
00503   GnuPlot.SetXYLabel(Info.Val2, Info.Val3);
00504   GnuPlot.SetScale(Info.Val4);
00505   int plotId;
00506   for (int at = 0; at < Len(); at++) {
00507     TStr Legend = At(at)->GetNm();
00508     if (Legend.Empty()) { Legend = At(at)->GetTmStr(); }
00509     if (! ExpBin) { 
00510       plotId = GnuPlot.AddPlot(At(at)->GetDistr(Distr), PlotWith, Legend, Style); }
00511     else { 
00512       TFltPrV ExpBinV; 
00513       TGnuPlot::MakeExpBins(At(at)->GetDistr(Distr), ExpBinV, 2, 0);
00514       plotId = GnuPlot.AddPlot(ExpBinV, PlotWith, Legend, Style);
00515     }
00516     if (PowerFit) { GnuPlot.AddPwrFit(plotId, gpwLines); }
00517   }
00518   GnuPlot.SavePng();
00519 }
00520 
00521 void TGStatVec::SaveTxt(const TStr& FNmPref, const TStr& Desc) const {
00522   FILE *F = fopen(TStr::Fmt("growth.%s.tab", FNmPref.CStr()).CStr(), "wt");
00523   fprintf(F, "# %s\n", Desc.CStr());
00524   fprintf(F, "# %s", TTmInfo::GetTmUnitStr(TmUnit).CStr());
00525   TIntSet StatValSet;
00526   for (int i = 0; i < Len(); i++) {
00527     for (int v = gsvNone; v < gsvMx; v++) {
00528       if (At(i)->HasVal(TGStatVal(v))) { StatValSet.AddKey(v); }
00529     }
00530   }
00531   TIntV StatValV;  StatValSet.GetKeyV(StatValV);  StatValV.Sort();
00532   for (int sv = 0; sv < StatValV.Len(); sv++) {
00533     fprintf(F, "\t%s", TGStat::GetValStr(TGStatVal(StatValV[sv].Val)).CStr()); }
00534   fprintf(F, "Time\n");
00535   for (int i = 0; i < Len(); i++) {
00536     const TGStat& G = *At(i);
00537     for (int sv = 0; sv < StatValV.Len(); sv++) {
00538       fprintf(F, "%g\t", G.GetVal(TGStatVal(StatValV[sv].Val))); }
00539     fprintf(F, "%s\n", G.GetTmStr().CStr());
00540   }
00541   fclose(F);
00542 }