void TNetInfBs::GenCascade(TCascade& C, const int& TModel, const double &window, TIntPrIntH& EdgesUsed, const double& delta, const double& std_waiting_time, const double& std_beta) { TIntFltH InfectedNIdH; TIntH InfectedBy; double GlobalTime; int StartNId; double alpha, beta; if (GroundTruth->GetNodes() == 0) return; while (C.Len() < 2) { C.Clr(); InfectedNIdH.Clr(); InfectedBy.Clr(); GlobalTime = 0; StartNId = GroundTruth->GetRndNId(); InfectedNIdH.AddDat(StartNId) = GlobalTime; while (true) { // sort by time & get the oldest node that did not run infection InfectedNIdH.SortByDat(true); const int& NId = InfectedNIdH.BegI().GetKey(); GlobalTime = InfectedNIdH.BegI().GetDat(); // all the nodes has run infection if (GlobalTime >= window) break; // add current oldest node to the network and set its time C.Add(NId, GlobalTime); // run infection from the current oldest node const TNGraph::TNodeI NI = GroundTruth->GetNI(NId); for (int e = 0; e < NI.GetOutDeg(); e++) { const int DstNId = NI.GetOutNId(e); beta = Betas.GetDat(TIntPr(NId, DstNId)); // flip biased coin (set by beta) if (TInt::Rnd.GetUniDev() > beta+std_beta*TFlt::Rnd.GetNrmDev()) continue; alpha = Alphas.GetDat(TIntPr(NId, DstNId)); // not infecting the parent if (InfectedBy.IsKey(NId) && InfectedBy.GetDat(NId).Val == DstNId) continue; double sigmaT; switch (TModel) { case 0: // exponential with alpha parameter sigmaT = TInt::Rnd.GetExpDev(alpha); break; case 1: // power-law with alpha parameter sigmaT = TInt::Rnd.GetPowerDev(alpha); while (sigmaT < delta) { sigmaT = TInt::Rnd.GetPowerDev(alpha); } break; case 2: // rayleigh with alpha parameter sigmaT = TInt::Rnd.GetRayleigh(1/sqrt(alpha)); break; default: sigmaT = 1; break; } // avoid negative time diffs in case of noise if (std_waiting_time > 0) sigmaT = TFlt::GetMx(0.0, sigmaT + std_waiting_time*TFlt::Rnd.GetNrmDev()); double t1 = GlobalTime + sigmaT; if (InfectedNIdH.IsKey(DstNId)) { double t2 = InfectedNIdH.GetDat(DstNId); if (t2 > t1 && t2 != window) { InfectedNIdH.GetDat(DstNId) = t1; InfectedBy.GetDat(DstNId) = NId; } } else { InfectedNIdH.AddDat(DstNId) = t1; InfectedBy.AddDat(DstNId) = NId; } } // we cannot delete key (otherwise, we cannot sort), so we assign a big time (window cut-off) InfectedNIdH.GetDat(NId) = window; } } C.Sort(); for (TIntH::TIter EI = InfectedBy.BegI(); EI < InfectedBy.EndI(); EI++) { TIntPr Edge(EI.GetDat().Val, EI.GetKey().Val); if (!EdgesUsed.IsKey(Edge)) EdgesUsed.AddDat(Edge) = 0; EdgesUsed.GetDat(Edge) += 1; } }
int TAGMFast::MLEGradAscentParallel(const double& Thres, const int& MaxIter, const int ChunkNum, const int ChunkSize, const TStr PlotNm, const double StepAlpha, const double StepBeta) { //parallel time_t InitTime = time(NULL); uint64 StartTm = TSecTm::GetCurTm().GetAbsSecs(); TExeTm ExeTm, CheckTm; double PrevL = Likelihood(true); TIntFltPrV IterLV; int PrevIter = 0; int iter = 0; TIntV NIdxV(F.Len(), 0); for (int i = 0; i < F.Len(); i++) { NIdxV.Add(i); } TIntV NIDOPTV(F.Len()); //check if a node needs optimization or not 1: does not require optimization NIDOPTV.PutAll(0); TVec<TIntFltH> NewF(ChunkNum * ChunkSize); TIntV NewNIDV(ChunkNum * ChunkSize); for (iter = 0; iter < MaxIter; iter++) { NIdxV.Clr(false); for (int i = 0; i < F.Len(); i++) { if (NIDOPTV[i] == 0) { NIdxV.Add(i); } } IAssert (NIdxV.Len() <= F.Len()); NIdxV.Shuffle(Rnd); // compute gradient for chunk of nodes #pragma omp parallel for schedule(static, 1) for (int TIdx = 0; TIdx < ChunkNum; TIdx++) { TIntFltH GradV; for (int ui = TIdx * ChunkSize; ui < (TIdx + 1) * ChunkSize; ui++) { NewNIDV[ui] = -1; if (ui > NIdxV.Len()) { continue; } int u = NIdxV[ui]; // //find set of candidate c (we only need to consider c to which a neighbor of u belongs to) TUNGraph::TNodeI UI = G->GetNI(u); TIntSet CIDSet(5 * UI.GetDeg()); TIntFltH CurFU = F[u]; for (int e = 0; e < UI.GetDeg(); e++) { if (HOVIDSV[u].IsKey(UI.GetNbrNId(e))) { continue; } TIntFltH& NbhCIDH = F[UI.GetNbrNId(e)]; for (TIntFltH::TIter CI = NbhCIDH.BegI(); CI < NbhCIDH.EndI(); CI++) { CIDSet.AddKey(CI.GetKey()); } } if (CIDSet.Empty()) { CurFU.Clr(); } else { for (TIntFltH::TIter CI = CurFU.BegI(); CI < CurFU.EndI(); CI++) { //remove the community membership which U does not share with its neighbors if (! CIDSet.IsKey(CI.GetKey())) { CurFU.DelIfKey(CI.GetKey()); } } GradientForRow(u, GradV, CIDSet); if (Norm2(GradV) < 1e-4) { NIDOPTV[u] = 1; continue; } double LearnRate = GetStepSizeByLineSearch(u, GradV, GradV, StepAlpha, StepBeta, 5); if (LearnRate <= 1e-5) { NewNIDV[ui] = -2; continue; } for (int ci = 0; ci < GradV.Len(); ci++) { int CID = GradV.GetKey(ci); double Change = LearnRate * GradV.GetDat(CID); double NewFuc = CurFU.IsKey(CID)? CurFU.GetDat(CID) + Change : Change; if (NewFuc <= 0.0) { CurFU.DelIfKey(CID); } else { CurFU.AddDat(CID) = NewFuc; } } CurFU.Defrag(); } //store changes NewF[ui] = CurFU; NewNIDV[ui] = u; } } int NumNoChangeGrad = 0; int NumNoChangeStepSize = 0; for (int ui = 0; ui < NewNIDV.Len(); ui++) { int NewNID = NewNIDV[ui]; if (NewNID == -1) { NumNoChangeGrad++; continue; } if (NewNID == -2) { NumNoChangeStepSize++; continue; } for (TIntFltH::TIter CI = F[NewNID].BegI(); CI < F[NewNID].EndI(); CI++) { SumFV[CI.GetKey()] -= CI.GetDat(); } } #pragma omp parallel for for (int ui = 0; ui < NewNIDV.Len(); ui++) { int NewNID = NewNIDV[ui]; if (NewNID < 0) { continue; } F[NewNID] = NewF[ui]; } for (int ui = 0; ui < NewNIDV.Len(); ui++) { int NewNID = NewNIDV[ui]; if (NewNID < 0) { continue; } for (TIntFltH::TIter CI = F[NewNID].BegI(); CI < F[NewNID].EndI(); CI++) { SumFV[CI.GetKey()] += CI.GetDat(); } } // update the nodes who are optimal for (int ui = 0; ui < NewNIDV.Len(); ui++) { int NewNID = NewNIDV[ui]; if (NewNID < 0) { continue; } TUNGraph::TNodeI UI = G->GetNI(NewNID); NIDOPTV[NewNID] = 0; for (int e = 0; e < UI.GetDeg(); e++) { NIDOPTV[UI.GetNbrNId(e)] = 0; } } int OPTCnt = 0; for (int i = 0; i < NIDOPTV.Len(); i++) { if (NIDOPTV[i] == 1) { OPTCnt++; } } if (! PlotNm.Empty()) { printf("\r%d iterations [%s] %d secs", iter * ChunkSize * ChunkNum, ExeTm.GetTmStr(), int(TSecTm::GetCurTm().GetAbsSecs() - StartTm)); if (PrevL > TFlt::Mn) { printf(" (%f) %d g %d s %d OPT", PrevL, NumNoChangeGrad, NumNoChangeStepSize, OPTCnt); } fflush(stdout); } if ((iter - PrevIter) * ChunkSize * ChunkNum >= G->GetNodes()) { PrevIter = iter; double CurL = Likelihood(true); IterLV.Add(TIntFltPr(iter * ChunkSize * ChunkNum, CurL)); printf("\r%d iterations, Likelihood: %f, Diff: %f [%d secs]", iter, CurL, CurL - PrevL, int(time(NULL) - InitTime)); fflush(stdout); if (CurL - PrevL <= Thres * fabs(PrevL)) { break; } else { PrevL = CurL; } } } if (! PlotNm.Empty()) { printf("\nMLE completed with %d iterations(%s secs)\n", iter, int(TSecTm::GetCurTm().GetAbsSecs() - StartTm)); TGnuPlot::PlotValV(IterLV, PlotNm + ".likelihood_Q");[] } else {