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
|
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 }