void PrintMtx(const TKronMtx& FitMtxM, ofstream& TFile){ TFile << "Initiator matrix: "; size_t Dim = FitMtxM.GetDim(); for (size_t i = 0; i < Dim; ++i) for (size_t j = 0; j < Dim; ++j){ TFile << FitMtxM.At(i,j); if (!(i == Dim-1 && j == Dim-1)) TFile << ";"; } TFile << endl; }
void GetGraphs(const vector <TStr>& Parameters, const TStr& ModelGen, const TStr&ModelPlt) { PNGraph G; size_t PSize = Parameters.size(); if (GRAPHGEN >= PSize || MTXGEN >= PSize || KRONGEN >= PSize || KRONFIT >= PSize) Error("GetGraphs", "Wrong index in array of parameters"); GetModel(Parameters[GRAPHGEN], G); if (G->GetNodes() == 0) Error("GetGraphs", "Empty graph"); TFltPrV MDegIn, MDegOut; TSnap::GetInDegCnt(G, MDegIn); TSnap::GetOutDegCnt(G, MDegOut); PlotDegrees(Parameters, MDegIn, MDegOut, "model"); TFile << "Model nodes: " << G->GetNodes() << ", model edges: " << G->GetEdges() << endl; TFile << "Maximum output degree in model graph: " << MDegOut[MDegOut.Len()-1].GetVal1() << endl; TFile << "Maximum input degree in model graph: " << MDegIn[MDegIn.Len()-1].GetVal1() << endl; if (ModelGen == "model+kron"){ // generate (or read) Kronecker initiator matrix TKronMtx FitMtxM; if (!GetMtx(Parameters[MTXGEN], FitMtxM)) GenNewMtx(G, Parameters[KRONFIT], FitMtxM); PrintMtx(FitMtxM, TFile); TFile << "Scaling for the number of edges... " << endl; FitMtxM.SetForEdges(G->GetNodes(), G->GetEdges()); int ModelNodes = G->GetNodes(), ModelEdges = G->GetEdges(); Env = TEnv(Parameters[KRONGEN], TNotify::NullNotify); TStr IsDir = Env.GetIfArgPrefixStr("-isdir:", "false", "Produce directed graph (true, false)"); const TInt NIter = Env.GetIfArgPrefixInt("-i:", 1, "Number of iterations of Kronecker product"); if (pow(FitMtxM.GetDim(), static_cast<double>(NIter)) != ModelNodes) Error("GetGraphs", "Inconsistent value of -i: parameter, KronNodes != ModelNodes"); // in and out average degrees of Kronecker graphs TFltPrV KronDegAvgIn, KronDegAvgOut; GenKron(Parameters[KRONGEN], FitMtxM, KronDegAvgIn, KronDegAvgOut); PlotDegrees(Parameters, KronDegAvgIn, KronDegAvgOut, "kron"); } }
void GenKron(const TStr& Args, TKronMtx& FitMtx, TFltPrV& KronDegAvgIn, TFltPrV& KronDegAvgOut){ Env = TEnv(Args, TNotify::NullNotify); TExeTm ExecTime; // number of Kronecker graphs to generate const TInt NKron = Env.GetIfArgPrefixInt("-n:", 1, "Number of generated Kronecker graphs"); // iterations of Kronecker product const TInt NIter = Env.GetIfArgPrefixInt("-i:", 10, "Iterations of Kronecker product"); // is graph directed? TStr IsDir = Env.GetIfArgPrefixStr("-isdir:", "false", "Produce directed graph (true, false)"); TFlt ExpectedNodes = FitMtx.GetNodes(NIter), ExpectedEdges = FitMtx.GetEdges(NIter); TFile << "Kronecker nodes: " << ExpectedNodes << ", expected Kronecker edges: " << ExpectedEdges << endl; double Sec = 0.0; int AvgMaxOutDeg = 0, AvgMaxInDeg = 0, MinMaxOutDeg = 0, MaxMaxOutDeg = 0, MinMaxInDeg = 0, MaxMaxInDeg = 0; bool Dir = IsDir == "true" ? true : false; for (int i = 0; i < NKron; i++){ ExecTime.Tick(); PNGraph Kron = TKronMtx::GenFastKronecker(FitMtx, NIter, Dir, 0); Sec += ExecTime.GetSecs(); printf("Calculating maximum degree...\n"); int MaxOutDeg = GetMaxMinDeg(Kron, IsDir, "false", "true"), MaxInDeg = GetMaxMinDeg(Kron, IsDir, "true", "true"); CompareDeg(i, MaxOutDeg, MinMaxOutDeg, MaxMaxOutDeg, AvgMaxOutDeg); CompareDeg(i, MaxInDeg, MinMaxInDeg, MaxMaxInDeg, AvgMaxInDeg); //printf("Nodes count: %d, nodes with non-zero degree %d, edges count %d\n max deg = %d\n", kron->GetNodes(), TSnap::CntNonZNodes(kron), kron->GetEdges(), MaxDeg); if (i == NKron - 1){ //TFile << "Clustering coefficient: " << TSnap::GetClustCf(kron) << endl; //TSnap::PlotClustCf(kron,"kronSingle"); //TSnap::PlotHops(kron, "kronSingle"); TFile << "Maximum output degree in kron graph: " << "from " << MinMaxOutDeg << " to " << MaxMaxOutDeg << " (average: " << (double)AvgMaxOutDeg / (double)NKron << ")" << endl; TFile << "Maximum input degree in kron graph: " << "from " << MinMaxInDeg << " to " << MaxMaxInDeg << " (average: " << (double)AvgMaxInDeg / (double)NKron << ")" << endl; } AddDegreesStat(KronDegAvgIn, Kron, true); AddDegreesStat(KronDegAvgOut, Kron, false); } Sec /= NKron; GetAvgDegreeStat(KronDegAvgIn, NKron); GetAvgDegreeStat(KronDegAvgOut, NKron); KronDegAvgIn.Sort(); KronDegAvgOut.Sort(); TFile << "Average time of generation of Kronecker product: " << Sec << endl; }
void TNetInfBs::GenerateGroundTruth(const int& TNetwork, const int& NNodes, const int& NEdges, const TStr& NetworkParams) { TKronMtx SeedMtx; TStr MtxNm; switch (TNetwork) { // 2-dimension kronecker network case 0: printf("Kronecker graph for Ground Truth\n"); SeedMtx = TKronMtx::GetMtx(NetworkParams.CStr()); // 0.5,0.5,0.5,0.5 printf("\n*** Seed matrix:\n"); SeedMtx.Dump(); GroundTruth = TKronMtx::GenFastKronecker(SeedMtx, (int)TMath::Log2(NNodes), NEdges, true, 0); break; // forest fire network case 1: printf("Forest Fire graph for Ground Truth\n"); TStrV NetworkParamsV; NetworkParams.SplitOnAllCh(';', NetworkParamsV); TFfGGen FF(true, // BurnExpFireP NetworkParamsV[0].GetInt(), // StartNNodes (1) NetworkParamsV[1].GetFlt(), // ForwBurnProb (0.2) NetworkParamsV[2].GetFlt(), // BackBurnProb (0.17) NetworkParamsV[3].GetInt(), // DecayProb (1) NetworkParamsV[4].GetInt(), // Take2AmbasPrb (0) NetworkParamsV[5].GetInt()); // OrphanPrb (0) FF.GenGraph(NNodes, false); GroundTruth = FF.GetGraph(); break; } }
int main(int argc, char* argv[]) { Env = TEnv(argc, argv, TNotify::StdNotify); Env.PrepArgs( TStr::Fmt("Kronecker graphs. build: %s, %s. Time: %s", __TIME__, __DATE__, TExeTm::GetCurTm())); TExeTm ExeTm; Try Env = TEnv(argc, argv, TNotify::StdNotify); const TStr InFNm = Env.GetIfArgPrefixStr("-i:", "../as20graph.txt", "Input graph file (single directed edge per line)"); TStr OutFNm = Env.GetIfArgPrefixStr("-o:", "", "Output file prefix"); const TInt NZero = Env.GetIfArgPrefixInt("-n0:", 2, "Innitiator matrix size"); const TStr InitMtx = Env.GetIfArgPrefixStr("-m:", "0.9 0.7; 0.5 0.2", "Init Gradient Descent Matrix (R=random)").GetLc(); const TStr Perm = Env.GetIfArgPrefixStr("-p:", "d", "Initial node permutation: d:Degree, r:Random, o:Order").GetLc(); const TInt GradIter = Env.GetIfArgPrefixInt("-gi:", 50, "Gradient descent iterations"); const TFlt LrnRate = Env.GetIfArgPrefixFlt("-l:", 1e-5, "Learning rate"); const TFlt MnStep = Env.GetIfArgPrefixFlt("-mns:", 0.005, "Minimum gradient step"); const TFlt MxStep = Env.GetIfArgPrefixFlt("-mxs:", 0.05, "Maximum gradient step"); const TInt WarmUp = Env.GetIfArgPrefixInt("-w:", 10000, "Samples to warm up"); const TInt NSamples = Env.GetIfArgPrefixInt("-s:", 100000, "Samples per gradient estimation"); //const TInt GradType = Env.GetIfArgPrefixInt("-gt:", 1, "1:Grad1, 2:Grad2"); const bool ScaleInitMtx = Env.GetIfArgPrefixBool("-sim:", true, "Scale the initiator to match the number of edges"); const TFlt PermSwapNodeProb = Env.GetIfArgPrefixFlt("-nsp:", 1.0, "Probability of using NodeSwap (vs. EdgeSwap) MCMC proposal distribution"); if (OutFNm.Empty()) { OutFNm = TStr::Fmt("%s-fit%d", InFNm.GetFMid().CStr(), NZero()); } // load graph PNGraph G; if (InFNm.GetFExt().GetLc() == ".ungraph") { TFIn FIn(InFNm); G = TSnap::ConvertGraph<PNGraph>(TUNGraph::Load(FIn), true); } else if (InFNm.GetFExt().GetLc() == ".ngraph") { TFIn FIn(InFNm); G = TNGraph::Load(FIn); } else { G = TSnap::LoadEdgeList<PNGraph>(InFNm, 0, 1); } // fit TKronMtx InitKronMtx = InitMtx == "r" ? TKronMtx::GetRndMtx(NZero, 0.1) : TKronMtx::GetMtx(InitMtx); InitKronMtx.Dump("INIT PARAM", true); TKroneckerLL KronLL(G, InitKronMtx, PermSwapNodeProb); if (ScaleInitMtx) { InitKronMtx.SetForEdges(G->GetNodes(), G->GetEdges()); } KronLL.InitLL(G, InitKronMtx); InitKronMtx.Dump("SCALED PARAM", true); KronLL.SetPerm(Perm.GetCh(0)); double LogLike = 0; //if (GradType == 1) { LogLike = KronLL.GradDescent(GradIter, LrnRate, MnStep, MxStep, WarmUp, NSamples); //} else if (GradType == 2) { // LogLike = KronLL.GradDescent2(GradIter, LrnRate, MnStep, MxStep, WarmUp, NSamples); } //else{ Fail; } const TKronMtx& FitMtx = KronLL.GetProbMtx(); FILE *F = fopen(OutFNm.CStr(), "w"); fprintf(F, "Input\t%s\n", InFNm.CStr()); TStrV ParamV; Env.GetCmLn().SplitOnAllCh(' ', ParamV); fprintf(F, "Command line options\n"); for (int i = 0; i < ParamV.Len(); i++) { fprintf(F, "\t%s\n", ParamV[i].CStr() + (ParamV[i][0] == '-' ? 1 : 0)); } fprintf(F, "Loglikelihood\t%10.2f\n", LogLike); fprintf(F, "Absolute error (based on expected number of edges)\t%f\n", KronLL.GetAbsErr()); fprintf(F, "RunTime\t%g\n", ExeTm.GetSecs()); fprintf(F, "Estimated initiator\t%s\n", FitMtx.GetMtxStr().CStr()); fclose(F); Catch printf("\nrun time: %s (%s)\n", ExeTm.GetTmStr(), TSecTm::GetCurTm().GetTmStr().CStr()); return 0; }
void ReadMtx(const TStr& Mtx, const TInt& MtxSize, TKronMtx& FitMtx){ TFltV matrix; GetMtxFromSepLine(Mtx, ";", matrix); FitMtx.GenMtx(matrix.Len() / MtxSize); FitMtx.SetMtx(matrix); }
void GenRandomMtx(const int& MtxRndSize, TKronMtx& FitMtx){ FitMtx.SetRndMtx(MtxRndSize); }