double TAGMFast::LikelihoodForOneVar(const TFltV& AlphaKV, const int UID, const int CID, const double& Val) { TUNGraph::TNodeI UI = G->GetNI(UID); double L = 0.0, PNoEdge; int VID = 0; for (int e = 0; e < UI.GetDeg(); e++) { VID = UI.GetNbrNId(e); if (HOVIDSV[UID].IsKey(UI.GetNbrNId(e))) { continue; } if (! F[VID].IsKey(CID)) { PNoEdge = AlphaKV[e]; } else { PNoEdge = AlphaKV[e] * exp (- F[VID].GetDat(CID) * Val); } IAssert(PNoEdge <= 1.0 && PNoEdge >= 0.0); //PNoEdge = PNoEdge >= 1.0 - PNoCom? 1 - PNoCom: PNoEdge; L += log(1.0 - PNoEdge) + NegWgt * GetCom(VID, CID) * Val; // += ((PNoEdge * F[VID].GetDat(CID)) / (1.0 - PNoEdge) + NegWgt * F[VID].GetDat(CID)); } L -= NegWgt * (SumFV[CID] - GetCom(UID, CID)) * Val; //add regularization if (RegCoef > 0.0) { //L1 L -= RegCoef * Val; } if (RegCoef < 0.0) { //L2 L += RegCoef * Val * Val; } return L; }
/// extract community affiliation from F_uc void TAGMFast::GetCmtyVV(TVec<TIntV>& CmtyVV, const double Thres, const int MinSz) { CmtyVV.Gen(NumComs, 0); TIntFltH CIDSumFH(NumComs); for (int c = 0; c < SumFV.Len(); c++) { CIDSumFH.AddDat(c, SumFV[c]); } CIDSumFH.SortByDat(false); for (int c = 0; c < NumComs; c++) { int CID = CIDSumFH.GetKey(c); TIntFltH NIDFucH(F.Len() / 10); TIntV CmtyV; IAssert(SumFV[CID] == CIDSumFH.GetDat(CID)); if (SumFV[CID] < Thres) { continue; } for (int u = 0; u < F.Len(); u++) { int NID = u; if (! NodesOk) { NID = NIDV[u]; } if (GetCom(u, CID) >= Thres) { NIDFucH.AddDat(NID, GetCom(u, CID)); } } NIDFucH.SortByDat(false); NIDFucH.GetKeyV(CmtyV); if (CmtyV.Len() >= MinSz) { CmtyVV.Add(CmtyV); } } if ( NumComs != CmtyVV.Len()) { printf("Community vector generated. %d communities are ommitted\n", NumComs.Val - CmtyVV.Len()); } }
double TAGMFast::LikelihoodForRow(const int UID, const TIntFltH& FU) { double L = 0.0; TFltV HOSumFV; //adjust for Fv of v hold out if (HOVIDSV[UID].Len() > 0) { HOSumFV.Gen(SumFV.Len()); for (int e = 0; e < HOVIDSV[UID].Len(); e++) { for (int c = 0; c < SumFV.Len(); c++) { HOSumFV[c] += GetCom(HOVIDSV[UID][e], c); } } } TUNGraph::TNodeI NI = G->GetNI(UID); if (DoParallel && NI.GetDeg() > 10) { #pragma omp parallel for schedule(static, 1) for (int e = 0; e < NI.GetDeg(); e++) { int v = NI.GetNbrNId(e); if (v == UID) { continue; } if (HOVIDSV[UID].IsKey(v)) { continue; } double LU = log (1.0 - Prediction(FU, F[v])) + NegWgt * DotProduct(FU, F[v]); #pragma omp atomic L += LU; } for (TIntFltH::TIter HI = FU.BegI(); HI < FU.EndI(); HI++) { double HOSum = HOVIDSV[UID].Len() > 0? HOSumFV[HI.GetKey()].Val: 0.0;//subtract Hold out pairs only if hold out pairs exist double LU = NegWgt * (SumFV[HI.GetKey()] - HOSum - GetCom(UID, HI.GetKey())) * HI.GetDat(); L -= LU; } } else { for (int e = 0; e < NI.GetDeg(); e++) { int v = NI.GetNbrNId(e); if (v == UID) { continue; } if (HOVIDSV[UID].IsKey(v)) { continue; } L += log (1.0 - Prediction(FU, F[v])) + NegWgt * DotProduct(FU, F[v]); } for (TIntFltH::TIter HI = FU.BegI(); HI < FU.EndI(); HI++) { double HOSum = HOVIDSV[UID].Len() > 0? HOSumFV[HI.GetKey()].Val: 0.0;//subtract Hold out pairs only if hold out pairs exist L -= NegWgt * (SumFV[HI.GetKey()] - HOSum - GetCom(UID, HI.GetKey())) * HI.GetDat(); } } //add regularization if (RegCoef > 0.0) { //L1 L -= RegCoef * Sum(FU); } if (RegCoef < 0.0) { //L2 L += RegCoef * Norm2(FU); } return L; }
void GetMATRIX(FILE *f, VARPTR var, int flag) { GetCom(f, var, flag); /** str1 was set by GetCom */ CheckSquare(f, var, str1, str2); Check(f, var, 0); Check(f, var, 1); }
void GetSTRING(FILE *f, VARPTR var, int flag) { if (var->for_type != CHAR) { printf("incompatibility between the type %s and FORTRAN type %s for variable \"%s\"\n", SGetSciType(STRING), SGetForType(var->for_type), var->name); exit(1); } GetCom(f, var, flag); Check(f, var, 0); }
void GetSCALAR(FILE *f, VARPTR var, int flag) { int i1 = var->stack_position; GetCom(f, var, flag); /* Check(f,var,0); */ if (var->list_el == 0 ) { Fprintf(f, indent, "CheckScalar(%d,m%d,n%d);\n", i1, i1, i1); } else { sprintf(str1, "%de%d", i1, var->list_el); Fprintf(f, indent, "CheckListScalar(%d,%d,m%s,n%s);\n", i1, var->list_el, str1, str1); } }
void GetBMATRIX(FILE *f, VARPTR var, int flag) { if (var->for_type != INT && var->for_type != BOOLEAN) { printf("incompatibility between the type %s and FORTRAN type %s for variable \"%s\"\n", SGetSciType(var->type), SGetForType(var->for_type), var->name); exit(1); } var->for_type = BOOLEAN; GetCom(f, var, flag); /** str1 was set by GetCom */ CheckSquare(f, var, str1, str2); Check(f, var, 0); Check(f, var, 1); }
void GetVECTOR(FILE *f, VARPTR var, int flag) { int i1 = var->stack_position; GetCom(f, var, flag); Check(f, var, 0); if (var->list_el == 0 ) { Fprintf(f, indent, "CheckVector(%d,m%d,n%d);\n", i1, i1, i1); Fprintf(f, indent, "mn%d=m%d*n%d;\n", i1, i1, i1); AddDeclare1(DEC_INT, "mn%d", i1); } else { sprintf(str1, "%de%d", i1, var->list_el); Fprintf(f, indent, "CheckListVector(%d,%d,m%s,n%s);\n", i1, var->list_el, str1, str1); Fprintf(f, indent, "l%dmn%d=m%s*n%s;\n", i1, var->list_el, str1, str1); AddDeclare1(DEC_INT, "l%dmn%d", i1, var->list_el); } }
double TAGMFast::GetStepSizeByLineSearch(const int UID, const TIntFltH& DeltaV, const TIntFltH& GradV, const double& Alpha, const double& Beta, const int MaxIter) { double StepSize = 1.0; double InitLikelihood = LikelihoodForRow(UID); TIntFltH NewVarV(DeltaV.Len()); for(int iter = 0; iter < MaxIter; iter++) { for (int i = 0; i < DeltaV.Len(); i++){ int CID = DeltaV.GetKey(i); double NewVal = GetCom(UID, CID) + StepSize * DeltaV.GetDat(CID); if (NewVal < MinVal) { NewVal = MinVal; } if (NewVal > MaxVal) { NewVal = MaxVal; } NewVarV.AddDat(CID, NewVal); } if (LikelihoodForRow(UID, NewVarV) < InitLikelihood + Alpha * StepSize * DotProduct(GradV, DeltaV)) { StepSize *= Beta; } else { break; } if (iter == MaxIter - 1) { StepSize = 0.0; break; } } return StepSize; }
double TAGMFast::GradientForOneVar(const TFltV& AlphaKV, const int UID, const int CID, const double& Val) { TUNGraph::TNodeI UI = G->GetNI(UID); double Grad = 0.0, PNoEdge; int VID = 0; for (int e = 0; e < UI.GetDeg(); e++) { VID = UI.GetNbrNId(e); if (HOVIDSV[UID].IsKey(UI.GetNbrNId(e))) { continue; } if (! F[VID].IsKey(CID)) { continue; } PNoEdge = AlphaKV[e] * exp (- F[VID].GetDat(CID) * Val); IAssert(PNoEdge <= 1.0 && PNoEdge >= 0.0); //PNoEdge = PNoEdge >= 1.0 - PNoCom? 1 - PNoCom: PNoEdge; Grad += ((PNoEdge * F[VID].GetDat(CID)) / (1.0 - PNoEdge) + NegWgt * F[VID].GetDat(CID)); } Grad -= NegWgt * (SumFV[CID] - GetCom(UID, CID)); //add regularization if (RegCoef > 0.0) { //L1 Grad -= RegCoef; } if (RegCoef < 0.0) { //L2 Grad += 2 * RegCoef * Val; } return Grad; }
cdecl main() { dbg("\n\rSTART Main\n\r"); #ifdef __DebugThreadState SYS::printThreadsState(); #endif // 'RESTART' event EVENT_DI Event; SYS::getNetTime(Event.Time); Event.Channel=255; Event.ChangedTo=0; Events.EventDigitalInput(Event); #ifdef __DebugThreadState for(int i=0; i<8; i++) { U8 s=LastThreadStates[i]; if(s!=0) { Event.ChangedTo=s; Event.Time++; Event.Channel=210+i; Events.EventDigitalInput(Event); } } #endif //SYS::sleep(500); // for relay pause // not working!!! SYS::startKernel(); SYS::sleep(100); //***** Starting threads #if __MTU THREAD_POLL_MTU* ThdPM; COM_PARAMS cp; cp.com = 1; cp.speed = 19200; GetComParams(" mtu=",&cp); ThdPM = new THREAD_POLL_MTU(cp.com, cp.speed); ThdPM->count = GetU8ArrParam(" MTUs=",ThdPM->addrs,16); ThdPM->run(); #endif #if __I7K THREAD_I7K_POLL* ThdP; THREAD_I7K_SAMPLER* ThdS; { COM_PARAMS cp; #if __MTU cp.com = 2; #else cp.com = 2; #endif cp.speed = 38400; GetComParams(" i7k=",&cp); //ConPrint("\n\r Dbg 3"); //ConPrintf("\n\r Dbg cp %d %d", cp.com, cp.speed); ThdP = new THREAD_I7K_POLL(cp.com, cp.speed); ThdS = new THREAD_I7K_SAMPLER(); ThdP->run(); ThdS->run(); } #endif #if !defined(__NO_HLI) && (!defined(__7188XB) || !defined(__ConPort)) #define ThdHLI THREAD_HLI* ThdHLI1; { COM_PARAMS cp; #if __MTU cp.com = 3; cp.speed = 9600; #else cp.com = 1; cp.speed = 19200; #endif GetComParams(" hli=",&cp); __HLI_BaudRate = cp.speed; #if defined(__WIRE) || defined(__ARQ) ThdHLI1 = new THREAD_HLI(cp.com); #else ThdHLI1 = new THREAD_HLI(GetCom(cp.com)); #endif ThdHLI1->run(); } #endif #ifdef __GPS_TIME_NMEA THREAD_GPS* ThdGPS =new THREAD_GPS(); ThdGPS->run(); #endif #if !defined(__NO_STAT) THREAD_STAT* ThdStat =new THREAD_STAT(); ThdStat->run(); #endif //***** Infinite working loop (until Esc received) BOOL Quit=FALSE; while(TRUE) { while(ConBytesInRxB()) { char c=ConReadChar(); ConWriteChar(c); if(c==27) Quit=TRUE; } if(Quit || SYS::Stopping()) break; SYS::WDT_Refresh(); SYS::sleep(333); } SYS::stopKernel(); // all threads stopped automatically //**** deleting threads #ifdef ThdHLI delete ThdHLI1; #endif #ifdef __GPS_TIME_NMEA delete ThdGPS; #endif #if __I7K delete ThdS; delete ThdP; #endif #if __MTU delete ThdPM; #endif #if !defined(__NO_STAT) delete ThdStat; #endif //***** All done dbg("\n\rSTOP Main\n\r"); SYS::DelayMs(100); return 0; }
int TAGMFast::MLEGradAscent(const double& Thres, const int& MaxIter, const TStr PlotNm, const double StepAlpha, const double StepBeta) { time_t InitTime = time(NULL); TExeTm ExeTm, CheckTm; int iter = 0, PrevIter = 0; TIntFltPrV IterLV; TUNGraph::TNodeI UI; double PrevL = TFlt::Mn, CurL = 0.0; TIntV NIdxV(F.Len(), 0); for (int i = 0; i < F.Len(); i++) { NIdxV.Add(i); } IAssert(NIdxV.Len() == F.Len()); TIntFltH GradV; while(iter < MaxIter) { NIdxV.Shuffle(Rnd); for (int ui = 0; ui < F.Len(); ui++, iter++) { int u = NIdxV[ui]; // //find set of candidate c (we only need to consider c to which a neighbor of u belongs to) UI = G->GetNI(u); TIntSet CIDSet(5 * UI.GetDeg()); 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()); } } for (TIntFltH::TIter CI = F[u].BegI(); CI < F[u].EndI(); CI++) { //remove the community membership which U does not share with its neighbors if (! CIDSet.IsKey(CI.GetKey())) { DelCom(u, CI.GetKey()); } } if (CIDSet.Empty()) { continue; } GradientForRow(u, GradV, CIDSet); if (Norm2(GradV) < 1e-4) { continue; } double LearnRate = GetStepSizeByLineSearch(u, GradV, GradV, StepAlpha, StepBeta); if (LearnRate == 0.0) { continue; } for (int ci = 0; ci < GradV.Len(); ci++) { int CID = GradV.GetKey(ci); double Change = LearnRate * GradV.GetDat(CID); double NewFuc = GetCom(u, CID) + Change; if (NewFuc <= 0.0) { DelCom(u, CID); } else { AddCom(u, CID, NewFuc); } } if (! PlotNm.Empty() && (iter + 1) % G->GetNodes() == 0) { IterLV.Add(TIntFltPr(iter, Likelihood(false))); } } printf("\r%d iterations (%f) [%lu sec]", iter, CurL, time(NULL) - InitTime); fflush(stdout); if (iter - PrevIter >= 2 * G->GetNodes() && iter > 10000) { PrevIter = iter; CurL = Likelihood(); if (PrevL > TFlt::Mn && ! PlotNm.Empty()) { printf("\r%d iterations, Likelihood: %f, Diff: %f", iter, CurL, CurL - PrevL); } fflush(stdout); if (CurL - PrevL <= Thres * fabs(PrevL)) { break; } else { PrevL = CurL; } } } printf("\n"); printf("MLE for Lambda completed with %d iterations(%s)\n", iter, ExeTm.GetTmStr()); if (! PlotNm.Empty()) { TGnuPlot::PlotValV(IterLV, PlotNm + ".likelihood_Q"); } return iter; }
/// Newton method: DEPRECATED int TAGMFast::MLENewton(const double& Thres, const int& MaxIter, const TStr PlotNm) { TExeTm ExeTm; int iter = 0, PrevIter = 0; TIntFltPrV IterLV; double PrevL = TFlt::Mn, CurL; TUNGraph::TNodeI UI; TIntV NIdxV; G->GetNIdV(NIdxV); int CID, UID, NewtonIter; double Fuc, PrevFuc, Grad, H; while(iter < MaxIter) { NIdxV.Shuffle(Rnd); for (int ui = 0; ui < F.Len(); ui++, iter++) { if (! PlotNm.Empty() && iter % G->GetNodes() == 0) { IterLV.Add(TIntFltPr(iter, Likelihood(false))); } UID = NIdxV[ui]; //find set of candidate c (we only need to consider c to which a neighbor of u belongs to) TIntSet CIDSet; UI = G->GetNI(UID); if (UI.GetDeg() == 0) { //if the node is isolated, clear its membership and skip if (! F[UID].Empty()) { F[UID].Clr(); } continue; } for (int e = 0; e < UI.GetDeg(); e++) { if (HOVIDSV[UID].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()); } } for (TIntFltH::TIter CI = F[UID].BegI(); CI < F[UID].EndI(); CI++) { //remove the community membership which U does not share with its neighbors if (! CIDSet.IsKey(CI.GetKey())) { DelCom(UID, CI.GetKey()); } } if (CIDSet.Empty()) { continue; } for (TIntSet::TIter CI = CIDSet.BegI(); CI < CIDSet.EndI(); CI++) { CID = CI.GetKey(); //optimize for UID, CID //compute constants TFltV AlphaKV(UI.GetDeg()); for (int e = 0; e < UI.GetDeg(); e++) { if (HOVIDSV[UID].IsKey(UI.GetNbrNId(e))) { continue; } AlphaKV[e] = (1 - PNoCom) * exp(- DotProduct(UID, UI.GetNbrNId(e)) + GetCom(UI.GetNbrNId(e), CID) * GetCom(UID, CID)); IAssertR(AlphaKV[e] <= 1.0, TStr::Fmt("AlphaKV=%f, %f, %f", AlphaKV[e].Val, PNoCom.Val, GetCom(UI.GetNbrNId(e), CID))); } Fuc = GetCom(UID, CID); PrevFuc = Fuc; Grad = GradientForOneVar(AlphaKV, UID, CID, Fuc), H = 0.0; if (Grad <= 1e-3 && Grad >= -0.1) { continue; } NewtonIter = 0; while (NewtonIter++ < 10) { Grad = GradientForOneVar(AlphaKV, UID, CID, Fuc), H = 0.0; H = HessianForOneVar(AlphaKV, UID, CID, Fuc); if (Fuc == 0.0 && Grad <= 0.0) { Grad = 0.0; } if (fabs(Grad) < 1e-3) { break; } if (H == 0.0) { Fuc = 0.0; break; } double NewtonStep = - Grad / H; if (NewtonStep < -0.5) { NewtonStep = - 0.5; } Fuc += NewtonStep; if (Fuc < 0.0) { Fuc = 0.0; } } if (Fuc == 0.0) { DelCom(UID, CID); } else { AddCom(UID, CID, Fuc); } } } if (iter - PrevIter >= 2 * G->GetNodes() && iter > 10000) { PrevIter = iter; CurL = Likelihood(); if (PrevL > TFlt::Mn && ! PlotNm.Empty()) { printf("\r%d iterations, Likelihood: %f, Diff: %f", iter, CurL, CurL - PrevL); } fflush(stdout); if (CurL - PrevL <= Thres * fabs(PrevL)) { break; } else { PrevL = CurL; } } } if (! PlotNm.Empty()) { printf("\nMLE for Lambda completed with %d iterations(%s)\n", iter, ExeTm.GetTmStr()); TGnuPlot::PlotValV(IterLV, PlotNm + ".likelihood_Q"); } return iter; }
void TAGMFast::GradientForRow(const int UID, TIntFltH& GradU, const TIntSet& CIDSet) { GradU.Gen(CIDSet.Len()); TFltV HOSumFV; //adjust for Fv of v hold out if (HOVIDSV[UID].Len() > 0) { HOSumFV.Gen(SumFV.Len()); for (int e = 0; e < HOVIDSV[UID].Len(); e++) { for (int c = 0; c < SumFV.Len(); c++) { HOSumFV[c] += GetCom(HOVIDSV[UID][e], c); } } } TUNGraph::TNodeI NI = G->GetNI(UID); int Deg = NI.GetDeg(); TFltV PredV(Deg), GradV(CIDSet.Len()); TIntV CIDV(CIDSet.Len()); if (DoParallel && Deg + CIDSet.Len() > 10) { #pragma omp parallel for schedule(static, 1) for (int e = 0; e < Deg; e++) { if (NI.GetNbrNId(e) == UID) { continue; } if (HOVIDSV[UID].IsKey(NI.GetNbrNId(e))) { continue; } PredV[e] = Prediction(UID, NI.GetNbrNId(e)); } #pragma omp parallel for schedule(static, 1) for (int c = 0; c < CIDSet.Len(); c++) { int CID = CIDSet.GetKey(c); double Val = 0.0; for (int e = 0; e < Deg; e++) { int VID = NI.GetNbrNId(e); if (VID == UID) { continue; } if (HOVIDSV[UID].IsKey(VID)) { continue; } Val += PredV[e] * GetCom(VID, CID) / (1.0 - PredV[e]) + NegWgt * GetCom(VID, CID); } double HOSum = HOVIDSV[UID].Len() > 0? HOSumFV[CID].Val: 0.0;//subtract Hold out pairs only if hold out pairs exist Val -= NegWgt * (SumFV[CID] - HOSum - GetCom(UID, CID)); CIDV[c] = CID; GradV[c] = Val; } } else { for (int e = 0; e < Deg; e++) { if (NI.GetNbrNId(e) == UID) { continue; } if (HOVIDSV[UID].IsKey(NI.GetNbrNId(e))) { continue; } PredV[e] = Prediction(UID, NI.GetNbrNId(e)); } for (int c = 0; c < CIDSet.Len(); c++) { int CID = CIDSet.GetKey(c); double Val = 0.0; for (int e = 0; e < Deg; e++) { int VID = NI.GetNbrNId(e); if (VID == UID) { continue; } if (HOVIDSV[UID].IsKey(VID)) { continue; } Val += PredV[e] * GetCom(VID, CID) / (1.0 - PredV[e]) + NegWgt * GetCom(VID, CID); } double HOSum = HOVIDSV[UID].Len() > 0? HOSumFV[CID].Val: 0.0;//subtract Hold out pairs only if hold out pairs exist Val -= NegWgt * (SumFV[CID] - HOSum - GetCom(UID, CID)); CIDV[c] = CID; GradV[c] = Val; } } //add regularization if (RegCoef > 0.0) { //L1 for (int c = 0; c < GradV.Len(); c++) { GradV[c] -= RegCoef; } } if (RegCoef < 0.0) { //L2 for (int c = 0; c < GradV.Len(); c++) { GradV[c] += 2 * RegCoef * GetCom(UID, CIDV[c]); } } for (int c = 0; c < GradV.Len(); c++) { if (GetCom(UID, CIDV[c]) == 0.0 && GradV[c] < 0.0) { continue; } if (fabs(GradV[c]) < 0.0001) { continue; } GradU.AddDat(CIDV[c], GradV[c]); } for (int c = 0; c < GradU.Len(); c++) { if (GradU[c] >= 10) { GradU[c] = 10; } if (GradU[c] <= -10) { GradU[c] = -10; } IAssert(GradU[c] >= -10); } }