15   MtxDim = (int) sqrt((
double)SeedMatrix.
Len());
 
   20   if (
this != &Kronecker){
 
   28   for (
int i = 0; i < 
Len(); i++) {
 
   29     if (
At(i) < 0.0 || 
At(i) > 1.0) 
return false;
 
   45   for (
int i = 0; i < 
Len(); i++) {
 
   47     if (Val == Eps1Val) Val = double(Eps1);
 
   48     else if (Val == Eps0Val) Val = double(Eps0);
 
   56   for (
int i = 0; i < 
Len(); i++) {
 
   57     for(c = 0; ((NewVal = 
At(i)*Rnd.
GetNrmDev(1, SDev, 0.8, 1.2)) < 0.01 || NewVal>0.99) && c <1000; c++) { }
 
   58     if (c < 999) { 
At(i) = NewVal; } 
else { printf(
"XXXXX\n"); }
 
   65   for (
int i = 0; i < 
Len(); i++) {
 
   67     if ((i+1)%
GetDim()==0 && (i+1<
Len())) { ChA += 
"; "; }
 
   68     else if (i+1<
Len()) { ChA += 
" "; }
 
   76   for (
int i = 0; i < 
Len(); i++) {
 
   77     if (
At(i) != 0.0) { LLMtx.
At(i) = log(
At(i)); }
 
   78     else { LLMtx.
At(i) = 
NInf; }
 
   84   for (
int i = 0; i < 
Len(); i++) {
 
   85     if (
At(i) != 
NInf) { ProbMtx.
At(i) = exp(
At(i)); }
 
   86     else { ProbMtx.
At(i) = 0.0; }
 
   97   for (
int i = 0; i < 
Len(); i++) {
 
  104   for (
int c = 0; c < 
GetDim(); c++) {
 
  105     Sum += 
At(RowId, c); }
 
  111   for (
int r = 0; r < 
GetDim(); r++) {
 
  112     Sum += 
At(r, ColId); }
 
  122         for(
int i = 0; i < 
Len(); i++) {
 
  134   if (! MtxNm.
Empty()) printf(
"%s\n", MtxNm.
CStr());
 
  137   if (Sort) { ValV.
Sort(
false); }
 
  138   for (
int i = 0; i < ValV.
Len(); i++) {
 
  139     printf(
"  %10.4g", ValV[i]());
 
  141     if ((i+1) % 
GetDim() == 0) { printf(
"\n"); }
 
  143   printf(
" (sum:%.4f)\n", Sum);
 
  153   for (
int i = 0; i < P1.
Len(); i++) {
 
  154     delta += fabs(P1[i] - P2[i]);
 
  156   return delta/P1.
Len();
 
  166   for (
int i = 0; i < P1.
Len(); i++) {
 
  167     delta += pow(P1[i] - P2[i], 2);
 
  169   return sqrt(delta/P1.
Len());
 
  174   TStrV RowStrV, ColStrV;
 
  177   RowStrV[0].SplitOnWs(ColStrV);    
IAssert(! ColStrV.
Empty());
 
  178   const int Rows = RowStrV.
Len();
 
  179   const int Cols = ColStrV.
Len();
 
  182   for (
int r = 0; r < Rows; r++) {
 
  183     RowStrV[r].SplitOnWs(ColStrV);
 
  185     for (
int c = 0; c < Cols; c++) {
 
  186       Mtx.
At(r, c) = (double) ColStrV[c].GetFlt(); }
 
  206         for(
int i = 0; i < NNodes; i++) {
 
  207                 for(
int l = 0; l < 
Dim; l++) {
 
  208                         if((TMAGNodeSimple::Rnd).GetUniDev() > 
Mu) {
 
  216         FILE *fp = fopen(InFNm.
CStr(), 
"r");
 
  217         IAssertR(fp != NULL, 
"File does not exist: " + InFNm);
 
  224         token = strtok(buf, 
"&");
 
  225         token = strtok(token, 
" \t");
 
  226         TokenStr = 
TStr(token);
 
  235         for(
int i = 0; i < 
Dim; i++) {
 
  255         for(
int i = 0; i < NNodes; i++) {
 
  256                 for(
int l = 0; l < 
Dim; l++) {
 
  257                         if((TMAGNodeBern::Rnd).GetUniDev() > 
MuV[l]) {
 
  265         FILE *fp = fopen(InFNm.
CStr(), 
"r");
 
  266         IAssertR(fp != NULL, 
"File does not exist: " + InFNm);
 
  276         while(fgets(buf, 
sizeof(buf), fp) != NULL) {
 
  277                 token = strtok(buf, 
"&");
 
  278                 token = strtok(token, 
" \t");
 
  279                 TokenStr = 
TStr(token);
 
  290         for(
int i = 0; i < 
Dim; i++) {
 
  330         for(
int i = 0; i < NNodes; i++) {
 
  331                 for(
int l = 0; l < 
Dim; l++) {
 
  334                         MuV[l] = x / (x + y);
 
  335                         if((TMAGNodeBeta::Rnd).GetUniDev() > 
MuV[l]) {
 
  344         FILE *fp = fopen(InFNm.
CStr(), 
"r");
 
  345         IAssertR(fp != NULL, 
"File does not exist: " + InFNm);
 
  356         while(fgets(buf, 
sizeof(buf), fp) != NULL) {
 
  357                 token = strtok(buf, 
"&");
 
  359                 token = strtok(token, 
" \t");
 
  360                 TokenStr = 
TStr(token);
 
  363                 token = strtok(NULL, 
" \t");
 
  364                 TokenStr = 
TStr(token);
 
  376         for(
int i = 0; i < 
Dim; i++) {
 
  390         if (! 
Graph->
IsNode(nid)) { NodesOk=
false; 
break; } }
 
  406         for(
int l = 0; l < NAttrs; l++) {
 
  407                 for(
int i = 0; i < NNodes; i++) {
 
  408                         if(
int(AttrVV(i, l)) == 0) {
 
  409                                 PhiVV(i, l) = 0.9999;
 
  411                                 PhiVV(i, l) = 0.0001;
 
  430         FILE *fp = fopen(FNm.
GetCStr(), 
"w");
 
  431         for(
int l = 0; l < NAttrs; l++) {
 
  432                 fprintf(fp, 
"%.4f\t", 
double(MuV[l]));
 
  433                 for(
int row = 0; row < 2; row++) {
 
  434                         for(
int col = 0; col < 2; col++) {
 
  435                                 fprintf(fp, 
" %.4f", 
double(MtxV[l].At(row, col)));
 
  437                         fprintf(fp, (row == 0) ? 
";" : 
"\n");
 
  442         fp = fopen((FNm + 
"f").CStr(), 
"w");
 
  443         for(
int i = 0; i < NNodes; i++) {
 
  444                 for(
int l = 0; l < NAttrs; l++) {
 
  445                         fprintf(fp, 
"%f ", 
double(
PhiVV(i, l)));
 
  466 void TMAGFitBern::PerturbInit(
const TFltV& MuV, 
const TMAGAffMtxV& AffMtxV, 
const double& PerturbRate) {
 
  478         for(
int l = 0; l < NAttrs; l++) {
 
  479                 double Mu = MuV[l] + PerturbRate * (Rnd.
GetUniDev() - 0.5) * 2;
 
  481                 if(Mu < 0.01) {  Mu = 0.01;  }
 
  482                 if(Mu > 0.99) {  Mu = 0.99;  }
 
  483                 DistParam.SetMu(l, Mu);
 
  486                 for(
int p = 0; p < 4; p++) {
 
  487                         AffMtx.At(p) += PerturbRate * (Rnd.
GetUniDev() - 0.5) * 2;
 
  488                         if(AffMtx.At(p) < 0.05) {  AffMtx.At(p) = 0.05;  }
 
  489                         if(AffMtx.At(p) > 0.95) {  AffMtx.At(p) = 0.95;  }
 
  491                 AffMtx.At(0, 1) = AffMtx.At(1, 0);
 
  492                 PerturbMtxV[l] = AffMtx;
 
  497         for(
int l = 0; l < NAttrs; l++) {
 
  498                 printf(
"Mu = %.3f  ", DistParam.GetMu(l));
 
  499                 printf(
"AffMtx = %s\n", PerturbMtxV[l].GetMtxStr().GetCStr());
 
  525         for(
int i = 0; i < NNodes; i++) {
 
  526                 for(
int l = 0; l < NAttrs; l++) {
 
  533         for(
int l = 0; l < NAttrs; l++) {
 
  534                 for(
int p = 0; p < 4; p++) {
 
  535                         RndMtxV[l].At(p) = TMAGNodeBern::Rnd.
GetUniDev();
 
  536                         if(RndMtxV[l].At(p) < 0.1) {  RndMtxV[l].At(p) = 0.1;  }
 
  537                         if(RndMtxV[l].At(p) > 0.9) {  RndMtxV[l].At(p) = 0.9;  }
 
  539                 RndMtxV[l].At(0, 1) = RndMtxV[l].At(1, 0);
 
  543         for(
int l = 0; l < NAttrs; l++) {
 
  544                 printf(
"AffMtx = %s\n", RndMtxV[l].GetMtxStr().GetCStr());
 
  560         const double Mu_l = 
AvgPhiV[AId] / double(NNodes);
 
  561         return (Mu_l * Theta.
At(0, A) + (1.0 - Mu_l) * Theta.
At(1, A));
 
  566         const double Mu_l = 
AvgPhiV[AId] / double(NNodes);
 
  567         return (Mu_l * Theta.
At(A, 0) + (1.0 - Mu_l) * Theta.
At(A, 1));
 
  570 const double TMAGFitBern::GetProbPhi(
const int& NId1, 
const int& NId2, 
const int& AId, 
const int& Attr1, 
const int& Attr2)
 const {
 
  571         double Prob1 = (Attr1 == 0) ? 
double(
PhiVV.
At(NId1, AId)) : (1.0 - 
PhiVV.
At(NId1, AId));
 
  572         double Prob2 = (Attr2 == 0) ? 
double(
PhiVV.
At(NId2, AId)) : (1.0 - 
PhiVV.
At(NId2, AId));
 
  573         return (Prob1 * Prob2);
 
  576 const double TMAGFitBern::GetProbMu(
const int& NId1, 
const int& NId2, 
const int& AId, 
const int& Attr1, 
const int& Attr2, 
const bool Left, 
const bool Right)
 const {
 
  580         double Prob1 = (Left) ? 
double(
PhiVV.
At(NId1, AId)) : 
double(Mu);
 
  581         double Prob2 = (Right)? 
double(
PhiVV.
At(NId2, AId)) : 
double(Mu);
 
  582         Prob1 = (Attr1 == 0) ? Prob1 : 1.0 - Prob1;
 
  583         Prob2 = (Attr2 == 0) ? Prob2 : 1.0 - Prob2;
 
  584         return (Prob1 * Prob2);
 
  590         for(
int A1 = 0; A1 < 2; A1++) {
 
  591                 for(
int A2 = 0; A2 < 2; A2++) {
 
  592                         LL += 
GetProbPhi(NId1, NId2, AId, A1, A2) * Mtx.
At(A1, A2);
 
  601         for(
int A1 = 0; A1 < 2; A1++) {
 
  602                 for(
int A2 = 0; A2 < 2; A2++) {
 
  603                         LL += 
GetProbMu(NId1, NId2, AId, A1, A2, Left, Right) * Mtx.
At(A1, A2);
 
  612         for(
int A1 = 0; A1 < 2; A1++) {
 
  613                 for(
int A2 = 0; A2 < 2; A2++) {
 
  614                         LL += 
GetProbPhi(NId1, NId2, AId, A1, A2) * Mtx.
At(A1, A2) * Mtx.
At(A1, A2);
 
  623         for(
int A1 = 0; A1 < 2; A1++) {
 
  624                 for(
int A2 = 0; A2 < 2; A2++) {
 
  625                         LL += 
GetProbMu(NId1, NId2, AId, A1, A2, Left, Right) * Mtx.
At(A1, A2) * Mtx.
At(A1, A2);
 
  635         for(
int l = 0; l < NAttrs; l++) {
 
  646         for(
int l = 0; l < NAttrs; l++) {
 
  657         for(
int l = 0; l < NAttrs; l++) {
 
  668         for(
int l = 0; l < NAttrs; l++) {
 
  675 const double LogSumExp(
const double LogVal1, 
const double LogVal2) {
 
  676         double MaxExp = (LogVal1 > LogVal2) ? LogVal1 : LogVal2;
 
  677         double Sum = exp(LogVal1 - MaxExp) + exp(LogVal2 - MaxExp);
 
  678         return (log(Sum) + MaxExp);
 
  682         const int Len = LogValV.
Len();
 
  685         for(
int i = 0; i < Len; i++) {
 
  686                 if(MaxExp < LogValV[i]) {  MaxExp = LogValV[i];  }
 
  690         for(
int i = 0; i < Len; i++) {
 
  691                 Sum += exp(LogValV[i] - MaxExp);
 
  694         return (log(Sum) + MaxExp);
 
  697 const double LogSumExp(
const double *LogValArray, 
const int Len) {
 
  699         for(
int i = 0; i < Len; i++) {  TmpV[i] = LogValArray[i];  }
 
  703 const double TMAGFitBern::GradPhiMI(
const double& x, 
const int& NId, 
const int& AId, 
const double& Lambda, 
const double& DeltaQ, 
const TFltVV& CntVV) {
 
  704         const int NAttrs = CntVV.
GetYDim();
 
  705         double Grad = DeltaQ - log(x) + log(1.0-x);
 
  707         for(
int l = 0; l < NAttrs; l++) {
 
  708                 if(l == AId) {  
continue;  }
 
  709                 const double C0 = 
PhiVV(NId, l);
 
  710                 const double C1 = 1.0 - C0;
 
  711                 Grad -= Lambda * C0 * log(CntVV(0, l) + C0 * x);
 
  712                 Grad -= Lambda * C1 * log(CntVV(1, l) + C1 * x);
 
  713                 Grad += Lambda * C0 * log(CntVV(2, l) + C0 * (1-x));
 
  714                 Grad += Lambda * C1 * log(CntVV(3, l) + C1 * (1-x));
 
  715                 Grad -= Lambda * log(CntVV(0, l) + CntVV(1, l) + x);
 
  716                 Grad += Lambda * log(CntVV(2, l) + CntVV(3, l) + (1-x));
 
  722 const double TMAGFitBern::ObjPhiMI(
const double& x, 
const int& NId, 
const int& AId, 
const double& Lambda, 
const double& Q0, 
const double& Q1, 
const TFltVV& CntVV) {
 
  723         const int NAttrs = CntVV.
GetYDim();
 
  724         double Val = x*(Q0 - log(x)) + (1-x)*(Q1 - log(1.0-x));
 
  726         for(
int l = 0; l < NAttrs; l++) {
 
  727                 if(l == AId) {  
continue;  }
 
  728                 const double C0 = 
PhiVV(NId, l);
 
  729                 const double C1 = 1.0 - C0;
 
  730                 Val -= Lambda * (CntVV(0, l) + C0 * x) * log(CntVV(0, l) + C0 * x);
 
  731                 Val -= Lambda * (CntVV(1, l) + C1 * x) * log(CntVV(1, l) + C1 * x);
 
  732                 Val -= Lambda * (CntVV(2, l) + C0 * (1-x)) * log(CntVV(2, l) + C0 * (1-x));
 
  733                 Val -= Lambda * (CntVV(3, l) + C1 * (1-x)) * log(CntVV(3, l) + C1 * (1-x));
 
  734                 Val += Lambda * (CntVV(0, l) + CntVV(1, l) + x) * log(CntVV(0, l) + CntVV(1, l) + x);
 
  735                 Val += Lambda * (CntVV(2, l) + CntVV(3, l) + 1 - x) * log(CntVV(2, l) + CntVV(3, l) + (1-x));
 
  737                 if(!(CntVV(0, l) > 0))  printf(
"CntVV(0, %d) = %.2f\n", l, 
double(CntVV(0, l)));
 
  738                 if(!(CntVV(1, l) > 0))  printf(
"CntVV(1, %d) = %.2f\n", l, 
double(CntVV(1, l)));
 
  739                 if(!(CntVV(2, l) > 0))  printf(
"CntVV(2, %d) = %.2f\n", l, 
double(CntVV(2, l)));
 
  740                 if(!(CntVV(3, l) > 0))  printf(
"CntVV(3, %d) = %.2f\n", l, 
double(CntVV(3, l)));
 
  763         const double Mu = DistParam.
GetMu(AId);
 
  765         for(
int i = 0; i < Theta.
Len(); i++) {
 
  766                 SqTheta.
At(i) = SqTheta.
At(i) * SqTheta.
At(i);
 
  770         double EdgeQ[2], NonEdgeQ[2], 
MaxExp[2];
 
  772         for(
int i = 0; i < 2; i++) {
 
  775                 MaxExp[i] = -DBL_MAX;
 
  776                 NonEdgeLLV[i].
Gen(4 * NNodes, 0);
 
  779         for(
int j = 0; j < NNodes; j++) {
 
  780                 if(j == NId) {  
continue;       }
 
  789                         for(
int i = 0; i < 2; i++) {
 
  790                                 NonEdgeLLV[i].
Add(LinW + log(
GetOutCoeff(NId, j, AId, i, Theta)));
 
  791                                 NonEdgeLLV[i].
Add(SqW + log(
GetOutCoeff(NId, j, AId, i, SqTheta)) + log(0.5));
 
  796                         EdgeQ[0] += 
GetInCoeff(j, NId, AId, 0, LLTheta);
 
  797                         EdgeQ[1] += 
GetInCoeff(j, NId, AId, 1, LLTheta);
 
  802                         for(
int i = 0; i < 2; i++) {
 
  803                                 NonEdgeLLV[i].
Add(LinW + log(
GetInCoeff(j, NId, AId, i, Theta)));
 
  804                                 NonEdgeLLV[i].
Add(SqW + log(
GetInCoeff(j, NId, AId, i, SqTheta)) + log(0.5));
 
  813         Q[0] = log(Mu) + EdgeQ[0] - exp(NonEdgeQ[0]);
 
  814         Q[1] = log(1.0 - Mu) + EdgeQ[1] - exp(NonEdgeQ[1]);
 
  822         return Phi - 
PhiVV.
At(NId, AId);
 
  833         const double Mu = DistParam.
GetMu(AId);
 
  835         for(
int i = 0; i < Theta.
Len(); i++) {
 
  836                 SqTheta.
At(i) = SqTheta.
At(i) * SqTheta.
At(i);
 
  840         double EdgeQ[2], NonEdgeQ[2], 
MaxExp[2];
 
  843         for(
int i = 0; i < 2; i++) {
 
  846                 MaxExp[i] = -DBL_MAX;
 
  847                 NonEdgeLLV[i].
Gen(4 * NNodes, 0);
 
  850         for(
int j = 0; j < NNodes; j++) {
 
  851                 if(j == NId) {  
continue;       }
 
  853                 for(
int l = 0; l < NAttrs; l++) {
 
  854                         if(l == AId) {  
continue;  }
 
  855                         CntVV(0, l) = CntVV(0, l) + 
PhiVV(j, AId) * 
PhiVV(j, l);
 
  856                         CntVV(1, l) = CntVV(1, l) + 
PhiVV(j, AId) * (1.0-
PhiVV(j, l));
 
  857                         CntVV(2, l) = CntVV(2, l) + (1.0-
PhiVV(j, AId)) * 
PhiVV(j, l);
 
  858                         CntVV(3, l) = CntVV(3, l) + (1.0-
PhiVV(j, AId)) * (1.0-
PhiVV(j, l));
 
  868                         for(
int i = 0; i < 2; i++) {
 
  869                                 NonEdgeLLV[i].
Add(LinW + log(
GetOutCoeff(NId, j, AId, i, Theta)));
 
  870                                 NonEdgeLLV[i].
Add(SqW + log(
GetOutCoeff(NId, j, AId, i, SqTheta)) + log(0.5));
 
  875                         EdgeQ[0] += 
GetInCoeff(j, NId, AId, 0, LLTheta);
 
  876                         EdgeQ[1] += 
GetInCoeff(j, NId, AId, 1, LLTheta);
 
  881                         for(
int i = 0; i < 2; i++) {
 
  882                                 NonEdgeLLV[i].
Add(LinW + log(
GetInCoeff(j, NId, AId, i, Theta)));
 
  883                                 NonEdgeLLV[i].
Add(SqW + log(
GetInCoeff(j, NId, AId, i, SqTheta)) + log(0.5));
 
  892         Q[0] = log(Mu) + EdgeQ[0] - exp(NonEdgeQ[0]);
 
  893         Q[1] = log(1.0 - Mu) + EdgeQ[1] - exp(NonEdgeQ[1]);
 
  894         double DeltaQ = Q[0] - Q[1];
 
  897         double x[] = {
PhiVV(NId, AId)};
 
  899         for(
int n = 0; n < 1; n++) {
 
  901                 double LrnRate = 0.001;
 
  902                 for(
int step = 0; step < 200; step++) {
 
  903                         double Grad = 
GradPhiMI(x[n], NId, AId, Lambda, DeltaQ, CntVV);
 
  904                         if(Grad > 0.0) {  x[n] += LrnRate;  }
 
  905                         else {  x[n] -= LrnRate;  }
 
  906                         if(x[n] > 0.9999) {  x[n] = 0.9999;  }
 
  907                         if(x[n] < 0.0001) {  x[n] = 0.0001;  }
 
  912         double MaxVal = -DBL_MAX;
 
  915         for(
int n = 0; n < 1; n++) {
 
  916                 double Val = 
ObjPhiMI(x[n], NId, AId, Lambda, Q[0], Q[1], CntVV);
 
  926         return Phi - 
PhiVV.
At(NId, AId);
 
  936         const double Mu = DistParam.
GetMu(AId);
 
  939         for(
int i = 0; i < Theta.
Len(); i++) {
 
  940                 SqTheta.
At(i) = SqTheta.
At(i) * SqTheta.
At(i);
 
  950         double EdgeQ[2], 
MaxExp[2];
 
  953         for(
int i = 0; i < 2; i++) {
 
  955                 MaxExp[i] = -DBL_MAX;
 
  956                 NonEdgeLLV[i].
Gen(4 * NNodes, 0);
 
  959         for(
int F = 0; F < 2; F++) {
 
  965         EdgeQ[0] = -(NNodes - 1) * exp(
LogSumExp(NonEdgeLLV[0]));
 
  966         EdgeQ[1] = -(NNodes - 1) * exp(
LogSumExp(NonEdgeLLV[1]));
 
  969         for(
int l = 0; l < NAttrs; l++) {
 
  970                 if(l == AId) {  
continue;  }
 
  971                 int BgId = (AId > l) ? AId : l;
 
  972                 int SmId = (AId + l) - BgId;
 
  973                 int SmL = (l < AId) ? 1 : 0;
 
  982         for(
int d = 0; d < NI.
GetOutDeg(); d++) {
 
  984                 if(NId == Out) {  
continue;  }
 
  988                 for(
int F = 0; F < 2; F++) {
 
  989                         EdgeQ[F] += 
GetOutCoeff(NId, Out, AId, F, LLTheta);
 
  990                         EdgeQ[F] += exp(LinW + log(
GetOutCoeff(NId, Out, AId, F, Theta)));
 
  991                         EdgeQ[F] += 0.5 * exp(SqW + log(
GetOutCoeff(NId, Out, AId, F, SqTheta)));
 
  994         for(
int d = 0; d < NI.
GetInDeg(); d++) {
 
  996                 if(NId == In) {  
continue;  }
 
 1000                 for(
int F = 0; F < 2; F++) {
 
 1001                         EdgeQ[F] += 
GetInCoeff(In, NId, AId, F, LLTheta);
 
 1002                         EdgeQ[F] += exp(LinW + log(
GetInCoeff(In, NId, AId, F, Theta)));
 
 1003                         EdgeQ[F] += 0.5 * exp(SqW + log(
GetInCoeff(In, NId, AId, F, SqTheta)));
 
 1007         EdgeQ[0] += log(Mu);
 
 1008         EdgeQ[1] += log(1.0 - Mu);
 
 1009         double DeltaQ = EdgeQ[0] - EdgeQ[1];
 
 1013         double x[] = {
PhiVV(NId, AId)};
 
 1016         for(
int n = 0; n < 1; n++) {
 
 1018                 double LrnRate = 0.001;
 
 1019                 for(
int step = 0; step < 50; step++) {
 
 1021                         double Grad = 
GradPhiMI(x[n], NId, AId, Lambda, DeltaQ, CntVV);
 
 1022                         if(Grad > 0.0) {  x[n] += LrnRate;  }
 
 1023                         else {  x[n] -= LrnRate;  }
 
 1024                         if(x[n] > 0.9999) {  x[n] = 0.9999;  }
 
 1025                         if(x[n] < 0.0001) {  x[n] = 0.0001;  }
 
 1026                         if(x[n] == 0.9999 || x[n] == 0.0001) {
 
 1035         double MaxVal = -DBL_MAX;
 
 1038         for(
int n = 0; n < ObjValV.
Len(); n++) {
 
 1039                 double Val = 
ObjPhiMI(ObjValV[n], NId, AId, Lambda, EdgeQ[0], EdgeQ[1], CntVV);
 
 1043                 } 
else if(MaxX < 0) {
 
 1044                         printf(
"(%d, %d) : %f  Q[0] = %f  Q[1] = %f  Val = %f\n", NId, AId, 
double(x[n]), 
double(EdgeQ[0]), 
double(EdgeQ[1]), Val);
 
 1049         Phi = ObjValV[MaxX];
 
 1051         return Phi - 
PhiVV.
At(NId, AId);
 
 1059         double MaxDelta = 0, L1 = 0;
 
 1065         TIntV NIndV(NNodes), AIndV(NAttrs);
 
 1077         NewVal.
Gen(NAttrs * 2);
 
 1078         for(
int i = 0; i < NNodes; i++) {
 
 1080                 for(
int l = 0; l < NAttrs * 2; l++) {
 
 1081                         const int NId = TMAGNodeBern::Rnd.
GetUniDevInt(NNodes);
 
 1082                         const int AId = TMAGNodeBern::Rnd.
GetUniDevInt(NAttrs);
 
 1096                         if(fabs(Delta) > MaxDelta) {
 
 1097                                 MaxDelta = fabs(Delta);
 
 1099                         if(Val > 0.3 && Val < 0.7) {    RndCount++;     }
 
 1102                 for(
int l = 0; l < NAttrs * 2; l++) {
 
 1103                         const int NId = NewVal[l].Val2;
 
 1104                         const int AId = NewVal[l].Val3;
 
 1105                         PhiVV.
At(NId, AId) = NewVal[l].Val1;
 
 1108         for(
int i = 0; i < NNodes; i++) {
 
 1109                 for(
int l = 0; l < NAttrs; l++) {
 
 1110                         MuV[l] = MuV[l] + 
PhiVV.
At(i, l);
 
 1113         for(
int l = 0; l < NAttrs; l++) {
 
 1114                 MuV[l] = MuV[l] / double(NNodes);
 
 1117         TFltV SortMuV = MuV;
 
 1119         SortMuV.
Sort(
false);
 
 1120         for(
int l = 0; l < NAttrs; l++) {
 
 1121                 printf(
"  F[%d] = %.3f", l, 
double(MuV[l]));
 
 1123                 L1 += fabs(TrueMuV[l] - SortMuV[l]);
 
 1126         printf(
"  Rnd = %d(%.3f)", RndCount, 
double(RndCount) / 
double(NNodes * NAttrs));
 
 1127         printf(
"  Avg = %.3f\n", Avg / 
double(NAttrs));
 
 1128         L1 /= double(NAttrs);
 
 1137         double MaxDelta = 0, L1 = 0;
 
 1144         TIntV NIndV(NNodes), AIndV(NAttrs);
 
 1158         for(
int i = 0; i < NNodes; i++) {
 
 1159                 for(
int l = 0; l < NAttrs; l++) {
 
 1160                         for(
int p = l+1; p < NAttrs; p++) {
 
 1170         for(
int i = 0; i < NNodes; i++) {
 
 1179         NewVal.
Gen(NAttrs * Iter);
 
 1180         for(
int i = 0; i < NNodes * Iter; i++) {
 
 1181                 for(
int l = 0; l < NAttrs; l++) {
 
 1182                         const int NId = TMAGNodeBern::Rnd.
GetUniDevInt(NNodes);
 
 1183                         const int AId = TMAGNodeBern::Rnd.
GetUniDevInt(NAttrs);
 
 1195                         if(fabs(Delta) > MaxDelta) {
 
 1196                                 MaxDelta = fabs(Delta);
 
 1198                         if(Val > 0.3 && Val < 0.7) {    RndCount++;     }
 
 1201                 for(
int l = 0; l < NAttrs; l++) {
 
 1202                         const int NId = NewVal[l].Val2;
 
 1203                         const int AId = NewVal[l].Val3;
 
 1205                         ProdVV(NId, 0) -= 
GetAvgThetaLL(NId, NId, AId, 
true, 
false);
 
 1206                         ProdVV(NId, 1) -= 
GetAvgThetaLL(NId, NId, AId, 
false, 
true);
 
 1209                         for(
int p = 0; p < NAttrs; p++) {
 
 1216                                 } 
else if (p < AId) {
 
 1217                                         int index = 4 * AId;
 
 1226                         PhiVV.
At(NId, AId) = NewVal[l].Val1;
 
 1228                         ProdVV(NId, 0) += 
GetAvgThetaLL(NId, NId, AId, 
true, 
false);
 
 1229                         ProdVV(NId, 1) += 
GetAvgThetaLL(NId, NId, AId, 
false, 
true);
 
 1232                         for(
int p = 0; p < NAttrs; p++) {
 
 1239                                 } 
else if (p < AId) {
 
 1240                                         int index = 4 * AId;
 
 1251         for(
int l = 0; l < NAttrs; l++) {
 
 1252                 MuV[l] = 
AvgPhiV[l] / double(NNodes);
 
 1255         TFltV SortMuV = MuV;
 
 1258         for(
int l = 0; l < NAttrs; l++) {
 
 1259                 printf(
"  F[%d] = %.3f", l, 
double(MuV[l]));
 
 1264         printf(
"  Rnd = %d(%.3f)", RndCount, 
double(RndCount) / 
double(NNodes * NAttrs));
 
 1265         printf(
"  Avg = %.3f\n", Avg / 
double(NAttrs));
 
 1275         TFltVV NewPhiVV(NNodes, NAttrs);
 
 1280         for(
int i = 0; i < NIter; i++) {
 
 1282                 printf(
"EStep iteration : %d\n", (i+1));
 
 1290                 printf(
"  (Time = %s)\n", IterTm.
GetTmStr());
 
 1296         return Delta.
Last();
 
 1302         const double OldMu = DistParam.
GetMu(AId);
 
 1305         for(
int i = 0; i < NNodes; i++) {
 
 1309         NewMu /= double(NNodes);
 
 1311         printf(
"      [Posterior Mu] = %.4f\n", NewMu);
 
 1313         double Delta = fabs(NewMu - OldMu);
 
 1314         DistParam.
SetMu(AId, NewMu);
 
 1325         for(
int i = 0; i < NNodes; i++) {
 
 1326                 for(
int j = 0; j < NNodes; j++) {
 
 1327                         double Prod = ProdVV(i, j) - 
GetThetaLL(i, j, AId);
 
 1330                         for(
int p = 0; p < 4; p++) {
 
 1335                                         GradV[p] += Prob / CurMtx.
At(p);
 
 1337                                         GradV[p] -= Prob * exp(Prod);
 
 1338                                         GradV[p] -= Prob * exp(Sq) * CurMtx.
At(p);
 
 1353         for(
int p = 0; p < 4; p++) {
 
 1356                 LogSumV.
Gen(NNodes * 4, 0);
 
 1358                 for(
int i = 0; i < NNodes; i++) {
 
 1359                         const double LProd = ProdVV(i, 0) - 
GetAvgThetaLL(i, i, AId, 
true, 
false);
 
 1360                         const double LSq = SqVV(i, 0) - 
GetAvgSqThetaLL(i, i, AId, 
true, 
false);
 
 1361                         const double RProd = ProdVV(i, 1) - 
GetAvgThetaLL(i, i, AId, 
false, 
true);
 
 1362                         const double RSq = SqVV(i, 1) - 
GetAvgSqThetaLL(i, i, AId, 
false, 
true);
 
 1364                         LogSumV.
Add(LProd + log(
GetProbMu(i, i, AId, Ai, Aj, 
true, 
false)));
 
 1365                         LogSumV.
Add(LSq + log(
GetProbMu(i, i, AId, Ai, Aj, 
true, 
false)) + log(CurMtx.
At(p)));
 
 1366                         LogSumV.
Add(RProd + log(
GetProbMu(i, i, AId, Ai, Aj, 
false, 
true)));
 
 1367                         LogSumV.
Add(RSq + log(
GetProbMu(i, i, AId, Ai, Aj, 
false, 
true)) + log(CurMtx.
At(p)));
 
 1370                 GradV[p] -= (NNodes - 1) * 0.5 * exp(LogSum);
 
 1374                 const int NId1 = EI.GetSrcNId();
 
 1375                 const int NId2 = EI.GetDstNId();
 
 1379                 for(
int p = 0; p < 4; p++) {
 
 1382                         double Prob = 
GetProbPhi(NId1, NId2, AId, Ai, Aj);
 
 1383                         GradV[p] += Prob / CurMtx.
At(p);
 
 1384                         GradV[p] += Prob * exp(ProdOne);
 
 1385                         GradV[p] += Prob * exp(SqOne) * CurMtx.
At(p);
 
 1390         const double Prod = ProdVV(0, 0) - 
GetAvgThetaLL(0, 0, AId, 
false, 
false);
 
 1391         const double Sq = SqVV(0, 0) - 
GetAvgSqThetaLL(0, 0, AId, 
false, 
false);
 
 1392         for(
int p = 0; p < 4; p++) {
 
 1395                 GradV[p] -= NSq * exp(Prod) * 
GetProbMu(0, 0, AId, Ai, Aj, 
false, 
false);
 
 1396                 GradV[p] -= NSq * exp(Sq) * 
GetProbMu(0, 0, AId, Ai, Aj, 
false, 
false) * CurMtx.
At(p);
 
 1400                 const int NId1 = EI.GetSrcNId();
 
 1401                 const int NId2 = EI.GetDstNId();
 
 1405                 for(
int p = 0; p < 4; p++) {
 
 1408                         double Prob = 
GetProbPhi(NId1, NId2, AId, Ai, Aj);
 
 1429                 GradAffMtx(AId, ProdVV, SqVV, NewMtx, GradV);
 
 1433         for(
int p = 0; p < 4; p++) {
 
 1434                 if(fabs(Ratio * LrnRate * GradV[p]) > MaxGrad) {
 
 1435                         Ratio = MaxGrad / fabs(LrnRate * GradV[p]);
 
 1439         for(
int p = 0; p < 4; p++) {
 
 1440                 GradV[p] *= (Ratio * LrnRate);
 
 1441                 NewMtx.
At(p) = AffMtx.
At(p) + GradV[p];
 
 1443                 if(NewMtx.
At(p) < 0.0001) {  NewMtx.
At(p) = 0.0001;  }
 
 1446         printf(
"      [Attr = %d]\n", AId);
 
 1447     printf(
"        %s  + [%f, %f; %f %f]  ----->  %s\n", (AffMtx.
GetMtxStr()).GetCStr(), double(GradV[0]), double(GradV[1]), double(GradV[2]), double(GradV[3]), (NewMtx.
GetMtxStr()).GetCStr());
 
 1456         const int NAttrs = MtxV.
Len();
 
 1458         double Product = 1.0, ExpEdge = NNodes * (NNodes - 1);
 
 1460         TFltV SumV(NAttrs), EdgeSumV(NAttrs);
 
 1461         SumV.PutAll(0.0);       EdgeSumV.PutAll(0.0);
 
 1462         for(
int l = 0; l < NAttrs; l++) {
 
 1463                 double Mu = (UseMu) ? 
double(MuV[l]) : (
AvgPhiV[l] / double(NNodes));
 
 1464                 EdgeSumV[l] += Mu * Mu * MtxV[l].At(0, 0);
 
 1465                 EdgeSumV[l] += Mu * (1.0-Mu) * MtxV[l].At(0, 1);
 
 1466                 EdgeSumV[l] += Mu * (1.0-Mu) * MtxV[l].At(1, 0);
 
 1467                 EdgeSumV[l] += (1.0-Mu) * (1.0-Mu) * MtxV[l].At(1, 1);
 
 1468                 SumV[l] = SumV[l] + MtxV[l].At(0, 0);
 
 1469                 SumV[l] = SumV[l] + MtxV[l].At(0, 1);
 
 1470                 SumV[l] = SumV[l] + MtxV[l].At(1, 0);
 
 1471                 SumV[l] = SumV[l] + MtxV[l].At(1, 1);
 
 1473                 ExpEdge *= EdgeSumV[l];
 
 1481         for(
int l = 0; l < NAttrs; l++) {
 
 1482                 for(
int p = 0; p < 4; p++) {
 
 1483                         MtxV[l].At(p) = MtxV[l].At(p) * Product / SumV[l];
 
 1494         const int NAttrs = MtxV.
Len();
 
 1499         double ExpEdge = NNodes * (NNodes - 1);
 
 1500         for(
int l = 0; l < NAttrs; l++) {
 
 1502                 double EdgeSum = Mu * Mu * MtxV[l].At(0, 0);
 
 1503                 EdgeSum += Mu * (1.0-Mu) * MtxV[l].At(0, 1);
 
 1504                 EdgeSum += Mu * (1.0-Mu) * MtxV[l].At(1, 0);
 
 1505                 EdgeSum += (1.0-Mu) * (1.0-Mu) * MtxV[l].At(1, 1);
 
 1511         for(
int l = 0; l < NAttrs; l++) {
 
 1513                 for(
int p = 0; p < 4; p++) {
 
 1514                         if(MaxEntV[l].Val1 < MtxV[l].At(p)) {  MaxEntV[l].Val1 = MtxV[l].At(p);  }
 
 1517         MaxEntV.
Sort(
false);
 
 1519         for(
int l = 0; l < NAttrs; l++) {
 
 1520                 int CurId = MaxEntV[l].Val2;
 
 1521                 double Factor = pow(
NormConst, 1.0 / 
double(NAttrs - l));
 
 1522                 double MaxFactor = 0.9999 / MaxEntV[l].Val1;
 
 1523                 Factor = (Factor > MaxFactor) ? MaxFactor : Factor;
 
 1526                 for(
int p = 0; p < 4; p++) {
 
 1527                         MtxV[CurId].At(p) = MtxV[CurId].At(p) * Factor;
 
 1534         ProdVV.
Gen(NNodes, NNodes);
 
 1535         SqVV.
Gen(NNodes, NNodes);
 
 1537         for(
int i = 0; i < NNodes; i++) {
 
 1538                 for(
int j = 0; j < NNodes; j++) {
 
 1547         ProdVV.
Gen(NNodes, 2);
 
 1548         SqVV.
Gen(NNodes, 2);
 
 1550         for(
int i = 0; i < NNodes; i++) {
 
 1558 const double TMAGFitBern::UpdateAffMtxV(
const int& GradIter, 
const double& LrnRate, 
const double& MaxGrad, 
const double& Lambda, 
const int& NReal) {
 
 1564         double DecLrnRate = LrnRate, DecMaxGrad = MaxGrad;
 
 1566         TFltVV ProdVV(NNodes, NNodes), SqVV(NNodes, NNodes);
 
 1571         for(
int g = 0; g < GradIter; g++) {
 
 1578                 printf(
"    [Grad step = %d]\n", (g+1));
 
 1580                 for(
int l = NReal; l < NAttrs; l++) {
 
 1581                         UpdateAffMtx(l, DecLrnRate, DecMaxGrad, Lambda, ProdVV, SqVV, NewMtxV[l]);
 
 1593         printf( 
"\nFinal\n");
 
 1594         for(
int l = 0; l < NAttrs; l++) {
 
 1596                 for(
int p = 0; p < 4; p++) {
 
 1598                         Delta += fabs(OldMtxV[l].At(p) - NewMtxV[l].At(p));
 
 1599                         printf(
" %.4f ", 
double(NewMtxV[l].At(p)));
 
 1604         ProdVV.Clr();           SqVV.
Clr();
 
 1608 void TMAGFitBern::DoMStep(
const int& GradIter, 
const double& LrnRate, 
const double& MaxGrad, 
const double& Lambda, 
const int& NReal) {
 
 1611         double MuDelta = 0.0, AffMtxDelta = 0.0;
 
 1617         for(
int l = 0; l < NAttrs; l++) {
 
 1623         printf(
"  == Update Theta\n");
 
 1624         AffMtxDelta += 
UpdateAffMtxV(GradIter, LrnRate, MaxGrad, Lambda, NReal);
 
 1626         printf(
"Elpased time = %s\n", ExeTm.
GetTmStr());
 
 1630 void TMAGFitBern::DoEMAlg(
const int& NStep, 
const int& NEstep, 
const int& NMstep, 
const double& LrnRate, 
const double& MaxGrad, 
const double& Lambda, 
const double& ReInit, 
const int& NReal) {
 
 1641         printf(
"--------------------------------------------\n");
 
 1642         printf(
"Before EM Iteration\n");
 
 1643         printf(
"--------------------------------------------\n");
 
 1650         for(
int i = 0; i < NNodes; i++) {
 
 1651                 for(
int l = 0; l < NAttrs; l++) {
 
 1668         for(
int n = 0; n < NStep; n++) {
 
 1669                 printf(
"--------------------------------------------\n");
 
 1670                 printf(
"EM Iteration : %d\n", (n+1));
 
 1671                 printf(
"--------------------------------------------\n");
 
 1674                 for(
int i = 0; i < NNodes; i++) {
 
 1675                         for(
int l = 0; l < NAttrs; l++) {
 
 1676                                 if(!
KnownVV(i, l) && TMAGNodeBern::Rnd.GetUniDev() < ReInit) {
 
 1681                 DoEStep(InitMuV, NEstep, LL, Lambda);
 
 1685                 DoMStep(NMstep, LrnRate, MaxGrad, Lambda, NReal);
 
 1694                         printf(
"    ApxLL = %.2f (Const = %f)\n", LL, 
double(
NormConst));
 
 1705         CcdfV.
Gen(RawV.
Len(), 0);
 
 1707         for(
int i = 0; i < RawV.
Len(); i++) {
 
 1708                 if(RawV[i].Val2 <= 0) {  
continue;  }
 
 1709                 Total += RawV[i].Val2;
 
 1713         for(
int i = 1; i < CcdfV.
Len(); i++) {
 
 1714                 CcdfV[i].Val2 += CcdfV[i-1].Val2;
 
 1717         for(
int i = CcdfV.
Len() - 1; i > 0; i--) {
 
 1718                 CcdfV[i].Val2 = (Total - CcdfV[i-1].Val2) ;
 
 1719                 if(CcdfV[i].Val2 <= 0) {  printf(
"CCDF = %f\n", 
double(CcdfV[i].Val2));}
 
 1722         CcdfV[0].Val2 = Total;
 
 1739         TIntVV AttrVV(NNodes, NAttrs);
 
 1740         for(
int i = 0; i < NNodes; i++) {
 
 1741                 for(
int j = 0; j < NAttrs; j++) {
 
 1742                         if(
PhiVV(i, j) > TMAGNodeBern::Rnd.GetUniDev()) AttrVV(i, j) = 0;
 
 1743                         else AttrVV(i, j) = 1;
 
 1748         printf(
"%d edges created for MAG...\n", MAG->
GetEdges());
 
 1755     TGnuPlot InDegP(FNm + 
"-InDeg"), OutDegP(FNm + 
"-OutDeg"), SvalP(FNm + 
"-Sval"), SvecP(FNm + 
"-Svec"), WccP(FNm + 
"-Wcc"), HopP(FNm + 
"-Hop"), TriadP(FNm + 
"-Triad"), CcfP(FNm + 
"-Ccf");;
 
 1757     InDegP.SetXYLabel(
"Degree", 
"# of nodes");
 
 1758     OutDegP.SetXYLabel(
"Degree", 
"# of nodes");
 
 1759     SvalP.SetXYLabel(
"Rank", 
"Singular value");
 
 1760     SvecP.SetXYLabel(
"Rank", 
"Primary SngVec component");
 
 1761     WccP.SetXYLabel(
"Size of component", 
"# of components");
 
 1762     CcfP.
SetXYLabel(
"Degree", 
"Clustering coefficient");
 
 1763     HopP.SetXYLabel(
"Hops", 
"# of node pairs");
 
 1764     TriadP.SetXYLabel(
"# of triads", 
"# of participating nodes");
 
 1766     InDegP.SetScale(
gpsLog10XY);    InDegP.AddCmd(
"set key top right");
 
 1767     OutDegP.SetScale(
gpsLog10XY);   OutDegP.AddCmd(
"set key top right");
 
 1768     SvalP.SetScale(
gpsLog10XY);     SvalP.AddCmd(
"set key top right");
 
 1769     SvecP.SetScale(
gpsLog10XY);     SvecP.AddCmd(
"set key top right");
 
 1771     HopP.SetScale(
gpsLog10XY);      HopP.AddCmd(
"set key top right");
 
 1772     TriadP.SetScale(
gpsLog10XY);    TriadP.AddCmd(
"set key top right");
 
 1773         InDegP.ShowGrid(
false);
 
 1774         OutDegP.ShowGrid(
false);
 
 1775         SvalP.ShowGrid(
false);
 
 1776         SvecP.ShowGrid(
false);
 
 1778         HopP.ShowGrid(
false);
 
 1779         TriadP.ShowGrid(
false);
 
 1781         const TStr Style[2] = {
"lt 1 lw 3 lc rgb 'black'", 
"lt 2 lw 3 lc rgb 'red'"};
 
 1782         const TStr Name[2] = {
"Real", 
"MAG"};
 
 1786         TFltPrV InDegV, OutDegV, SvalV, SvecV, HopV, WccV, CcfV, TriadV;
 
 1787         for(
int i = 0; i < GS.
Len(); i++) {
 
 1796                 InDegP.AddPlot(InDegV, 
gpwLines, Name[i], Style[i]);
 
 1797                 OutDegP.AddPlot(OutDegV, 
gpwLines, Name[i], Style[i]);
 
 1798                 SvalP.AddPlot(SvalV, 
gpwLines, Name[i], Style[i]);
 
 1799                 SvecP.AddPlot(SvecV, 
gpwLines, Name[i], Style[i]);
 
 1801                 HopP.AddPlot(HopV, 
gpwLines, Name[i], Style[i]);
 
 1802                 TriadP.AddPlot(TriadV, 
gpwLines, Name[i], Style[i]);
 
 1806         OutDegP.SaveEps(30);
 
 1820         for(
int l = 0; l < NAttrs; l++) {
 
 1821                 for(
int i = 0; i < NNodes; i++) {
 
 1822                         EstMuV[l] = EstMuV[l] + 
PhiVV(i, l);
 
 1824                 EstMuV[l] = EstMuV[l] / double(NNodes);
 
 1829         const int NAttrs = TrueMuV.
Len();
 
 1831         TFltV EstMuV, SortedTrueMuV, SortedEstMuV, TrueIdxV, EstIdxV;
 
 1833         TrueIdxV.
Gen(NAttrs);
 
 1834         EstIdxV.
Gen(NAttrs);
 
 1836         for(
int l = 0; l < NAttrs; l++) {
 
 1842         SortedTrueMuV = TrueMuV;
 
 1843         SortedEstMuV = EstMuV;
 
 1844         for(
int i = 0; i < NAttrs; i++) {
 
 1845                 if(SortedTrueMuV[i] > 0.5) {  SortedTrueMuV[i] = 1.0 - SortedTrueMuV[i];  }
 
 1846                 if(SortedEstMuV[i] > 0.5) {  SortedEstMuV[i] = 1.0 - SortedEstMuV[i];  }
 
 1849         for(
int i = 0; i < NAttrs; i++) {
 
 1850                 for(
int j = i+1; j < NAttrs; j++) {
 
 1851                         if(SortedTrueMuV[i] < SortedTrueMuV[j]) {
 
 1852                                 SortedTrueMuV.
Swap(i, j);
 
 1853                                 TrueIdxV.
Swap(i, j);
 
 1855                         if(SortedEstMuV[i] < SortedEstMuV[j]) {
 
 1856                                 EstIdxV.
Swap((
int)SortedEstMuV[i], (
int)SortedEstMuV[j]);
 
 1857                                 SortedEstMuV.
Swap(i, j);
 
 1862         for(
int l = 0; l < NAttrs; l++) {
 
 1863                 IndexV[l] = (int)TrueIdxV[(
int)EstIdxV[l]];
 
 1868         const int NAttrs = IndexV.
Len();
 
 1869         int Pos = NAttrs - 1;
 
 1871                 if(IndexV[Pos-1] < IndexV[Pos]) {
 
 1880         int Val = NAttrs, NewPos = -1;
 
 1881         for(
int i = Pos; i < NAttrs; i++) {
 
 1882                 if(IndexV[i] > IndexV[Pos - 1] && IndexV[i] < Val) {
 
 1887         IndexV[NewPos] = IndexV[Pos - 1];
 
 1888         IndexV[Pos - 1] = Val;
 
 1891     IndexV.
GetSubValV(Pos, NAttrs - 1, SubIndexV);
 
 1892         SubIndexV.
Sort(
true);
 
 1893         for(
int i = Pos; i < NAttrs; i++) {
 
 1894                 IndexV[i] = SubIndexV[i - Pos];
 
 1908         for(
int l = 0; l < NAttrs; l++) {
 
 1909                 for(
int i = 0; i < MtxV[l].
Len(); i++) {
 
 1910                         MtxV[l].At(i) = log(MtxV[l].At(i));
 
 1914         for(
int i = 0; i < NNodes; i++) {
 
 1915                 for(
int l = 0; l < NAttrs; l++) {
 
 1916                         if(AttrVV.
At(i, l) == 0) {
 
 1919                                 LL += log(1.0 - MuV[l]);
 
 1923                 for(
int j = 0; j < NNodes; j++) {
 
 1924                         if(i == j) {  
continue;  }
 
 1926                         double ProbLL = 0.0;
 
 1927                         for(
int l = 0; l < NAttrs; l++) {
 
 1928                                 ProbLL += MtxV[l].At(AttrVV.
At(i, l), AttrVV.
At(j, l));
 
 1934                                 LL += log(1-exp(ProbLL));
 
 1950         for(
int l = 0; l < NAttrs; l++) {
 
 1951                 for(
int i = 0; i < MtxV[l].
Len(); i++) {
 
 1952                         MtxV[l].At(i) = log(MtxV[l].At(i));
 
 1956         for(
int i = 0; i < NNodes; i++) {
 
 1957                 for(
int j = 0; j < NNodes; j++) {
 
 1958                         if(i == j) {  
continue;  }
 
 1960                         double ProbLL = 0.0;
 
 1961                         for(
int l = 0; l < NAttrs; l++) {
 
 1962                                 ProbLL += MtxV[l].At(AttrVV.
At(i, l), AttrVV.
At(j, l));
 
 1968                                 LL += log(1-exp(ProbLL));
 
 1982         TIntVV AttrVV(NNodes, NAttrs);
 
 1984         for(
int s = 0; s < NSample; s++) {
 
 1985                 for(
int i = 0; i < NNodes; i++) {
 
 1986                         for(
int l = 0; l < NAttrs; l++) {
 
 1989                                         AttrVV.
At(i, l) = 0;
 
 1991                                         AttrVV.
At(i, l) = 1;
 
 1994                                 if(
PhiVV(i, l) > 0.05 && 
PhiVV(i, l) < 0.95) count++;
 
 2002         return LL / double(NSample);
 
 2014         for(
int l = 0; l < NAttrs; l++) {
 
 2015                 for(
int i = 0; i < NNodes; i++) {
 
 2016                         LL += 
PhiVV(i, l) * log(MuV[l]);
 
 2017                         LL += (1.0 - 
PhiVV(i, l)) * log(1.0 - MuV[l]);
 
 2019                         LL -= (1.0 - 
PhiVV(i, l)) * log(1.0 - 
PhiVV(i, l));
 
 2025         for(
int i = 0; i < NNodes; i++) {
 
 2026                 for(
int j = 0; j < NNodes; j++) {
 
 2027                         if(i == j) {  
continue;  }
 
 2030                                 for(
int l = 0; l < NAttrs; l++) {
 
 2031                                         LL += 
GetProbPhi(i, j, l, 0, 0) * LLMtxV[l].At(0, 0);
 
 2032                                         LL += 
GetProbPhi(i, j, l, 0, 1) * LLMtxV[l].At(0, 1);
 
 2033                                         LL += 
GetProbPhi(i, j, l, 1, 0) * LLMtxV[l].At(1, 0);
 
 2034                                         LL += 
GetProbPhi(i, j, l, 1, 1) * LLMtxV[l].At(1, 1);
 
 2055         double TotalEdge = 0.0;
 
 2056         for(
int l = 0; l < NAttrs; l++) {
 
 2061         for(
int i = 0; i < NNodes; i++) {
 
 2062                 for(
int j = 0; j < NNodes; j++) {
 
 2063                         if(i == j) {  
continue;  }
 
 2066                                 for(
int l = 0; l < NAttrs; l++) {
 
 2067                                         LL += 
GetProbPhi(i, j, l, 0, 0) * LLMtxV[l].At(0, 0);
 
 2068                                         LL += 
GetProbPhi(i, j, l, 0, 1) * LLMtxV[l].At(0, 1);
 
 2069                                         LL += 
GetProbPhi(i, j, l, 1, 0) * LLMtxV[l].At(1, 0);
 
 2070                                         LL += 
GetProbPhi(i, j, l, 1, 1) * LLMtxV[l].At(1, 1);
 
 2076                         double TempLL = 1.0;
 
 2077                         for(
int l = 0; l < NAttrs; l++) {
 
 2078                                 int Ai = (double(
PhiVV(i, l)) > 0.5) ? 0 : 1;
 
 2079                                 int Aj = (double(
PhiVV(j, l)) > 0.5) ? 0 : 1;
 
 2082                         if(TMAGNodeBern::Rnd.GetUniDev() < TempLL) {
 
 2092         const int NNodes = AttrV.
GetXDim();
 
 2102         for(
int i = 0; i < NNodes; i++) {
 
 2103                 int X = AttrV(i, AId1);
 
 2104                 int Y = AttrV(i, AId2);
 
 2105                 Pxy(X, Y) = Pxy(X, Y) + 1;
 
 2108                 Cor += double(X * Y);
 
 2111         for(
int x = 0; x < 2; x++) {
 
 2112                 for(
int y = 0; y < 2; y++) {
 
 2113       MI += Pxy(x, y) / double(NNodes) * (log(Pxy(x, y).Val) - log(Px[x].Val) - log(Py[y].Val) + log((
double)NNodes));
 
 2121         const int NNodes = AttrV.
GetXDim();
 
 2131         for(
int i = 0; i < NNodes; i++) {
 
 2132                 double X = AttrV(i, AId1);
 
 2133                 double Y = AttrV(i, AId2);
 
 2134                 Pxy(0, 0) = Pxy(0, 0) + X * Y;
 
 2135                 Pxy(0, 1) = Pxy(0, 1) + X * (1 - Y);
 
 2136                 Pxy(1, 0) = Pxy(1, 0) + (1 - X) * Y;
 
 2137                 Pxy(1, 1) = (i+1) - Pxy(0, 0) - Pxy(0, 1) - Pxy(1, 0);
 
 2140                 Cor += double((1-X) * (1-Y));
 
 2142         Px[1] = NNodes - Px[0];
 
 2143         Py[1] = NNodes - Py[0];
 
 2145         for(
int x = 0; x < 2; x++) {
 
 2146                 for(
int y = 0; y < 2; y++) {
 
 2147                         MI += Pxy(x, y) / double(NNodes) * (log(Pxy(x, y)) - log(Px[x]) - log(Py[y]) + log(
double(NNodes)));
 
 2156         const int NAttrs = AttrV.
GetYDim();
 
 2159         for(
int l = 0; l < NAttrs; l++) {
 
 2160                 for(
int k = l+1; k < NAttrs; k++) {
 
 2170         const int NAttrs = AttrV.
GetYDim();
 
 2173         for(
int l = 0; l < NAttrs; l++) {
 
 2174                 for(
int k = l+1; k < NAttrs; k++) {
 
const double ComputeJointAdjLL(const TIntVV &AttrVV) const 
 
void SetNodeAttr(const TNodeAttr &Dist)
 
TMAGNodeBern & operator=(const TMAGNodeBern &Dist)
 
const double GetAvgSqThetaLL(const int &NId1, const int &NId2, const int &AId, const bool Left=false, const bool Right=false) const 
 
void DoEMAlg(const int &NStep, const int &NEstep, const int &NMstep, const double &LrnRate, const double &MaxGrad, const double &Lambda, const double &ReInit, const int &NReal=0)
 
void GetNIdV(TIntV &NIdV) const 
Gets a vector IDs of all nodes in the graph. 
 
#define IAssertR(Cond, Reason)
 
const bool NextPermutation(TIntV &IndexV) const 
 
TPair< TFlt, TInt > TFltIntPr
 
const int GetAttrs() const 
 
TMAGParam< TMAGNodeBern > Param
 
const double GetAvgInCoeff(const int &i, const int &AId, const int &A, const TMAGAffMtx &Theta) const 
 
TMAGAffMtx & operator=(const TMAGAffMtx &Kronecker)
 
const double GetEstNoEdgeLL(const int &NId, const int &AId) const 
 
TNodeI GetNI(const int &NId) const 
Returns an iterator referring to the node of ID NId in the graph. 
 
void Swap(TMAGAffMtx &Mtx)
 
void Dump(const TStr &MtxNm=TStr(), const bool &Sort=false) const 
 
TEdgeI EndEI() const 
Returns an iterator referring to the past-the-end edge in the graph. 
 
static double GetAvgAbsErr(const TMAGAffMtx &Mtx1, const TMAGAffMtx &Mtx2)
 
void NormalizeAffMtxV(TMAGAffMtxV &MtxV, const bool UseMu=false)
 
const double GetOutCoeff(const int &i, const int &j, const int &l, const int &A, const TMAGAffMtx &Theta) const 
 
int GetEdges() const 
Returns the number of edges in the graph. 
 
TSizeTy Len() const 
Returns the number of elements in the vector. 
 
void MakeCCDF(const TFltPrV &RawV, TFltPrV &CcdfV)
 
TEdgeI BegEI() const 
Returns an iterator referring to the first edge in the graph. 
 
void CountAttr(TFltV &EstMuV) const 
 
int GetNodes() const 
Returns the number of nodes in the graph. 
 
void SetXYLabel(const TStr &XLabel, const TStr &YLabel)
 
void SaveTxt(TStrV &OutStrV) const 
 
double GetRowSum(const int &RowId) const 
 
TMAGNodeBeta & operator=(const TMAGNodeBeta &Dist)
 
const double UpdatePhiMI(const double &Lambda, const int &NId, const int &AId, double &Phi)
 
const double GetSqThetaLL(const int &NId1, const int &NId2, const int &AId) const 
 
const double GetProdSqWeight(const int &NId1, const int &NId2) const 
 
TVec< TMAGAffMtxV > MtxHisV
 
int ChangeChAll(const char &SrcCh, const char &DstCh)
 
void LoadTxt(const TStr &InFNm)
 
const void GradApxAffMtx(const int &AId, const TFltVV &ProdVV, const TFltVV &SqVV, const TMAGAffMtx &CurMtx, TFltV &GradV)
 
bool Empty() const 
Tests whether the vector is empty. 
 
double GetGammaDev(const int &Order)
 
void UnNormalizeAffMtxV(TMAGAffMtxV &MtxV, const bool UseMu=false)
 
const double LogSumExp(const double LogVal1, const double LogVal2)
 
void AttrGen(TIntVV &AttrVV, const int &NNodes)
 
void SetPhiVV(const TIntVV &AttrVV, const int KnownIds=0)
 
Graph Statistics Sequence. 
 
void Swap(TVec< TVal, TSizeTy > &Vec)
Swaps the contents of the vector with Vec. 
 
void RandomInit(const TFltV &MuV, const TMAGAffMtxV &AffMtxV, const int &Seed)
 
const char * GetTmStr() const 
 
static double GetAvgFroErr(const TMAGAffMtx &Mtx1, const TMAGAffMtx &Mtx2)
 
void GetMtxV(TMAGAffMtxV &MtxV) const 
 
void LoadTxt(const TStr &InFNm)
 
void DelZeroDegNodes(PGraph &Graph)
Removes all the zero-degree nodes, that isolated nodes, from the graph. 
 
void SetGraph(const PNGraph &GraphPt)
 
const double GetAvgProdSqWeight(const int &NId1, const int &NId2, const bool Left=false, const bool Right=false) const 
 
const double GetInCoeff(const int &i, const int &j, const int &l, const int &A, const TMAGAffMtx &Theta) const 
 
const void GradAffMtx(const int &AId, const TFltVV &ProdVV, const TFltVV &SqVV, const TMAGAffMtx &CurMtx, TFltV &GradV)
 
void PlotProperties(const TStr &FNm)
 
void AddCmd(const TStr &Cmd)
 
const TFltV & GetMuV() const 
 
void GetProbMtx(TMAGAffMtx &ProbMtx)
 
const double GetAvgThetaLL(const int &NId1, const int &NId2, const int &AId, const bool Left=false, const bool Right=false) const 
 
void Sort(const bool &Asc=true)
Sorts the elements of the vector. 
 
Edge iterator. Only forward iteration (operator++) is supported. 
 
const double UpdateAffMtx(const int &AId, const double &LrnRate, const double &MaxGrad, const double &Lambda, TFltVV &ProdVV, TFltVV &SqVV, TMAGAffMtx &NewMtx)
 
const void PrepareUpdateApxAffMtx(TFltVV &ProdVV, TFltVV &SqVV)
 
const double GetProdLinWeight(const int &NId1, const int &NId2) const 
 
const double UpdateMu(const int &AId)
 
const double ComputeJointOneLL(const TIntVV &AttrVV) const 
 
void PutAll(const TVal &Val)
Sets all elements of the vector to value Val. 
 
void SetBetaV(const TFltV &_AlphaV, const TFltV &_BetaV)
 
const TFltV & GetMuV() const 
 
bool IsEdge(const int &SrcNId, const int &DstNId, const bool &IsDir=true) const 
Tests whether an edge from node IDs SrcNId to DstNId exists in the graph. 
 
void PutAll(const TVal &Val)
 
const double GetThetaLL(const int &NId1, const int &NId2, const int &AId) const 
 
PUNGraph GetSubGraph(const PUNGraph &Graph, const TIntV &NIdV, const bool &RenumberNodes)
Returns an induced subgraph of an undirected graph Graph with NIdV nodes with an optional node renumb...
 
const double UpdatePhi(const int &NId, const int &AId, double &Phi)
 
bool IsNode(const int &NId) const 
Tests whether ID NId is a node. 
 
double GetMu(const int &Attr) const 
 
double GetColSum(const int &ColId) const 
 
double DoEStepOneIter(const TFltV &TrueMuV, TFltVV &NewPhi, const double &Lambda)
 
const TVal & Last() const 
Returns a reference to the last element of the vector. 
 
void AttrGen(TIntVV &AttrVV, const int &NNodes)
 
void SetBeta(const int &Attr, const double &Alpha, const double &Beta)
 
const double GetProbPhi(const int &NId1, const int &NId2, const int &AId, const int &Attr1, const int &Attr2) const 
 
double DoEStepApxOneIter(const TFltV &TrueMuV, TFltVV &NewPhi, const double &Lambda)
 
void SaveEps(const int &FontSz=30, const TStr &Comment=TStr())
 
void AttrGen(TIntVV &AttrVV, const int &NNodes)
 
void GetRow(const TSizeTy &RowN, TVec< TVal, TSizeTy > &Vec) const 
 
void SetMtxV(const TMAGAffMtxV &MtxV)
 
static TMAGAffMtx GetRndMtx(TRnd &Rnd, const int &Dim=2, const double &MinProb=0.0)
 
const double ComputeJointLL(int NSample) const 
 
const TMAGAffMtx & GetMtx(const int &Attr) const 
 
const double GetAvgProdLinWeight(const int &NId1, const int &NId2, const bool Left=false, const bool Right=false) const 
 
void SortAttrOrdering(const TFltV &TrueMuV, TIntV &IndexV) const 
 
PNGraph GenMAG(TIntVV &AttrVV, const bool &IsDir=false, const int &Seed=1)
 
void PutSeed(const int &_Seed)
 
PGStat At(const int &ValN) const 
 
const double ComputeApxAdjLL() const 
 
void SaveTxt(TStrV &OutStrV) const 
 
void SetScale(const TGpScaleTy &GpScaleTy)
 
int GetOutDeg() const 
Returns out-degree of the current node. 
 
void GetLLMtx(TMAGAffMtx &LLMtx)
 
const void PrepareUpdateAffMtx(TFltVV &ProdVV, TFltVV &SqVV)
 
static TStr Fmt(const char *FmtStr,...)
 
double DoEStep(const TFltV &TrueMuV, const int &NIter, double &LL, const double &Lambda)
 
const double GetAvgOutCoeff(const int &i, const int &AId, const int &A, const TMAGAffMtx &Theta) const 
 
const TNodeAttr & GetNodeAttr() const 
 
void SplitOnAllCh(const char &SplitCh, TStrV &StrV, const bool &SkipEmpty=true) const 
 
Node iterator. Only forward iteration (operator++) is supported. 
 
void SetMu(const int &Attr, const double &Prob)
 
void SetEpsMtx(const double &Eps1, const double &Eps0, const int &Eps1Val=1, const int &Eps0Val=0)
 
int AddPlot(const TIntV &YValV, const TGpSeriesTy &SeriesTy=gpwLinesPoints, const TStr &Label=TStr(), const TStr &Style=TStr())
 
void SetRndMtx(TRnd &Rnd, const int &PrmMtxDim=2, const double &MinProb=0.0)
 
void SaveTxt(const TStr &FNm)
 
const int GetNodes() const 
 
const double UpdateApxPhiMI(const double &Lambda, const int &NId, const int &AId, double &Phi, TFltVV &ProdVV)
 
void Gen(const TSizeTy &_Vals)
Constructs a vector (an array) of _Vals elements. 
 
void DoMStep(const int &GradIter, const double &LrnRate, const double &MaxGrad, const double &Lambda, const int &NReal=0)
 
const double & At(const int &Row, const int &Col) const 
 
int GetUniDevInt(const int &Range=0)
 
void ShowGrid(const bool &Show)
 
int GetInDeg() const 
Returns in-degree of the current node. 
 
void SaveTxt(TStrV &OutStrV) const 
 
int GetInNId(const int &NodeN) const 
Returns ID of NodeN-th in-node (the node pointing to the current node). 
 
TSizeTy Add()
Adds a new element at the end of the vector, after its current last element. 
 
static const double ComputeMI(const TIntVV &AttrV, const int AId1, const int AId2)
 
void AddRndNoise(TRnd &Rnd, const double &SDev)
 
const double UpdateAffMtxV(const int &GradIter, const double &LrnRate, const double &MaxGrad, const double &Lambda, const int &NReal=0)
 
void Init(const TFltV &MuV, const TMAGAffMtxV &AffMtxV)
 
int GetOutNId(const int &NodeN) const 
Returns ID of NodeN-th out-node (the node the current node points to). 
 
void Gen(const TSizeTy &_XDim, const TSizeTy &_YDim)
 
void PutY(const TSizeTy &Y, const TVal &Val)
 
TTriple< TFlt, TInt, TInt > TFltIntIntTr
 
const double ComputeApxLL() const 
 
const double ObjPhiMI(const double &x, const int &NId, const int &AId, const double &Lambda, const double &Q0, const double &Q1, const TFltVV &CntVV)
 
void LoadTxt(const TStr &InFNm)
 
void GenMtx(const int &Dim)
 
const double GetProbMu(const int &NId1, const int &NId2, const int &AId, const int &Attr1, const int &Attr2, const bool Left=false, const bool Right=false) const 
 
const double GradPhiMI(const double &x, const int &NId, const int &AId, const double &Lambda, const double &DeltaQ, const TFltVV &CntVV)
 
void GetSubValV(const TSizeTy &BValN, const TSizeTy &EValN, TVec< TVal, TSizeTy > &ValV) const 
Fills ValV with elements at positions BValN...EValN. 
 
const TVal & At(const TSizeTy &X, const TSizeTy &Y) const