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