void TIndex::TQmGixSumItemHandler<TQmGixItem>::Merge(TVec<TQmGixItem>& ItemV, const bool& IsLocal) const { if (ItemV.Empty()) { return; } // nothing to do in this case if (!ItemV.IsSorted()) { ItemV.Sort(); } // sort if not yet sorted // merge counts int LastItemN = 0; bool ZeroP = false; for (int ItemN = 1; ItemN < ItemV.Len(); ItemN++) { if (ItemV[ItemN].Key != ItemV[ItemN - 1].Key) { LastItemN++; ItemV[LastItemN] = ItemV[ItemN]; } else { ItemV[LastItemN].Dat += ItemV[ItemN].Dat; } ZeroP = ZeroP || (ItemV[LastItemN].Dat <= 0); } // remove items with zero count if (ZeroP) { int LastIndN = 0; for (int ItemN = 0; ItemN < LastItemN + 1; ItemN++) { const TQmGixItem& Item = ItemV[ItemN]; if (Item.Dat.Val > 0 || (IsLocal && Item.Dat.Val < 0)) { ItemV[LastIndN] = Item; LastIndN++; } else if (Item.Dat.Val < 0) { TEnv::Error->OnStatusFmt("Warning: negative item count %d:%d!", (int)Item.Key, (int)Item.Dat); } } ItemV.Reserve(ItemV.Reserved(), LastIndN); } else { ItemV.Reserve(ItemV.Reserved(), LastItemN + 1); } }
/////////////////////////////////////////////////////////////////////////////// // Triad counting methods void TempMotifCounter::Count3TEdgeTriadsNaive(double delta, Counter3D& counts) { TIntV Us, Vs, Ws; GetAllStaticTriangles(Us, Vs, Ws); counts = Counter3D(2, 2, 2); #pragma omp parallel for schedule(dynamic) for (int i = 0; i < Us.Len(); i++) { int u = Us[i]; int v = Vs[i]; int w = Ws[i]; // Gather all edges in triangle (u, v, w) int uv = 0, vu = 1, uw = 2, wu = 3, vw = 4, wv = 5; TVec<TIntPair> combined; AddStarEdges(combined, u, v, uv); AddStarEdges(combined, v, u, vu); AddStarEdges(combined, u, w, uw); AddStarEdges(combined, w, u, wu); AddStarEdges(combined, v, w, vw); AddStarEdges(combined, w, v, wv); // Get the counts for this triangle combined.Sort(); ThreeTEdgeMotifCounter counter(6); TIntV edge_id(combined.Len()); TIntV timestamps(combined.Len()); for (int k = 0; k < combined.Len(); k++) { edge_id[k] = combined[k].Dat; timestamps[k] = combined[k].Key; } Counter3D local; counter.Count(edge_id, timestamps, delta, local); // Update the global counter with the various symmetries #pragma omp critical { // i --> j, k --> j, i --> k counts(0, 0, 0) += local(uv, wv, uw) + local(vu, wu, vw) + local(uw, vw, uv) + local(wu, vu, wv) + local(vw, uw, vu) + local(wv, uv, wu); // i --> j, k --> j, k --> i counts(0, 0, 1) += local(uv, wv, wu) + local(vu, wu, wv) + local(uw, vw, vu) + local(wu, vu, vw) + local(vw, uw, uv) + local(wv, uv, uw); // i --> j, j --> k, i --> k counts(0, 1, 0) += local(uv, vw, uw) + local(vu, uw, vw) + local(uw, wv, uv) + local(wu, uv, wv) + local(vw, wu, vu) + local(wv, vu, wu); // i --> j, j --> k, k --> i counts(0, 1, 1) += local(uv, vw, wu) + local(vu, uw, wv) + local(uw, wv, vu) + local(wu, uv, vw) + local(vw, wu, uv) + local(wv, vu, uw); // i --> j, k --> i, j --> k counts(1, 0, 0) += local(uv, wu, vw) + local(vu, wv, uw) + local(uw, vu, wv) + local(wu, vw, uv) + local(vw, uv, wu) + local(wv, uw, vu); // i --> j, k --> i, k --> j counts(1, 0, 1) += local(uv, wu, wv) + local(vu, wv, wu) + local(uw, vu, vw) + local(wu, vw, vu) + local(vw, uv, uw) + local(wv, uw, uv); // i --> j, i --> k, j --> k counts(1, 1, 0) += local(uv, uw, vw) + local(vu, vw, uw) + local(uw, uv, wv) + local(wu, wv, uv) + local(vw, vu, wu) + local(wv, wu, vu); // i --> j, i --> k, k --> j counts(1, 1, 1) += local(uv, uw, wv) + local(vu, vw, wu) + local(uw, uv, vw) + local(wu, wv, vu) + local(vw, vu, uw) + local(wv, wu, uv); } } }
void TempMotifCounter::Count3TEdge3NodeStarsNaive( double delta, Counter3D& pre_counts, Counter3D& pos_counts, Counter3D& mid_counts) { TIntV centers; GetAllNodes(centers); pre_counts = Counter3D(2, 2, 2); pos_counts = Counter3D(2, 2, 2); mid_counts = Counter3D(2, 2, 2); // Get counts for each node as the center #pragma omp parallel for schedule(dynamic) for (int c = 0; c < centers.Len(); c++) { // Gather all adjacent events int center = centers[c]; TIntV nbrs; GetAllNeighbors(center, nbrs); for (int i = 0; i < nbrs.Len(); i++) { for (int j = i + 1; j < nbrs.Len(); j++) { int nbr1 = nbrs[i]; int nbr2 = nbrs[j]; TVec<TIntPair> combined; AddStarEdges(combined, center, nbr1, 0); AddStarEdges(combined, nbr1, center, 1); AddStarEdges(combined, center, nbr2, 2); AddStarEdges(combined, nbr2, center, 3); combined.Sort(); ThreeTEdgeMotifCounter counter(4); TIntV edge_id(combined.Len()); TIntV timestamps(combined.Len()); for (int k = 0; k < combined.Len(); k++) { edge_id[k] = combined[k].Dat; timestamps[k] = combined[k].Key; } Counter3D local; counter.Count(edge_id, timestamps, delta, local); #pragma omp critical { // Update with local counts for (int dir1 = 0; dir1 < 2; ++dir1) { for (int dir2 = 0; dir2 < 2; ++dir2) { for (int dir3 = 0; dir3 < 2; ++dir3) { pre_counts(dir1, dir2, dir3) += local(dir1, dir2, dir3 + 2) + local(dir1 + 2, dir2 + 2, dir3); pos_counts(dir1, dir2, dir3) += local(dir1, dir2 + 2, dir3 + 2) + local(dir1 + 2, dir2, dir3); mid_counts(dir1, dir2, dir3) += local(dir1, dir2 + 2, dir3) + local(dir1 + 2, dir2, dir3 + 2); } } } } } } } }
void TempMotifCounter::Count3TEdge2Node(int u, int v, double delta, Counter3D& counts) { // Sort event list by time TVec<TIntPair> combined; AddStarEdges(combined, u, v, 0); AddStarEdges(combined, v, u, 1); combined.Sort(); // Get the counts ThreeTEdgeMotifCounter counter(2); TIntV in_out(combined.Len()); TIntV timestamps(combined.Len()); for (int k = 0; k < combined.Len(); k++) { in_out[k] = combined[k].Dat; timestamps[k] = combined[k].Key; } counter.Count(in_out, timestamps, delta, counts); }
void TStrFeatureSpace::GetAddIdFreqs(const TStrV& Features, TVec<TKeyDat<TStrFSSize, TInt> >& IdFreqs) { TIntH Freqs; for (int i = 0; i < Features.Len(); i++) { int Id = GetAddId(Features[i]); TInt Freq = 0; if (Freqs.IsKeyGetDat(Id, Freq)) { Freqs.AddDat(Id, Freq + 1); } else { Freqs.AddDat(Id, 1); } } IdFreqs.Gen(Freqs.Len()); for (int i = 0; i < Freqs.Len(); i++) { TInt Key, Freq; Freqs.GetKeyDat(i, Key, Freq); IdFreqs[i].Key = Key; IdFreqs[i].Dat = Freq; } IdFreqs.Sort(); }
void TStrFeatureSpace::GetIdFreqs(const TVec<const char *>& Features, TVec<TKeyDat<TStrFSSize, TInt> >& IdFreqs) const { TIntH Freqs; for (int i = 0; i < Features.Len(); i++) { TInt Id; if (GetIfExistsId(Features[i], Id)) { TInt Freq = 0; if (Freqs.IsKeyGetDat(Id, Freq)) { Freqs.AddDat(Id, Freq + 1); } else { Freqs.AddDat(Id, 1); } } } IdFreqs.Gen(Freqs.Len()); for (int i = 0; i < Freqs.Len(); i++) { TInt Key, Freq; Freqs.GetKeyDat(i, Key, Freq); IdFreqs[i].Key = Key; IdFreqs[i].Dat = Freq; } IdFreqs.Sort(); }
TIntPr TNetInfBs::GetBestEdge(double& CurProb, double& LastGain, bool& msort, int &attempts) { TIntPr BestE; TVec<TInt> KeysV; TVec<TPair<TFlt, TIntPr> > EdgeGainCopyToSortV; TIntV EdgeZero; double BestGain = TFlt::Mn; int BestGainIndex = -1; if (msort) { for (int i=0; i<TMath::Mn(attempts-1, EdgeGainV.Len()); i++) EdgeGainCopyToSortV.Add(EdgeGainV[i]); // printf("Sorting sublist of size %d of marginal gains!\n", EdgeGainCopyToSortV.Len()); // sort this list EdgeGainCopyToSortV.Sort(false); // printf("Sublist sorted!\n"); // clever way of resorting without need to copy (google interview question! :-)) for (int i=0, ii=0, j=0; ii < EdgeGainCopyToSortV.Len(); j++) { if ( (i+EdgeGainCopyToSortV.Len() < EdgeGainV.Len()) && (EdgeGainCopyToSortV[ii].Val1 < EdgeGainV[i+EdgeGainCopyToSortV.Len()].Val1) ) { EdgeGainV[j] = EdgeGainV[i+EdgeGainCopyToSortV.Len()]; i++; } else { EdgeGainV[j] = EdgeGainCopyToSortV[ii]; ii++; } } } attempts = 0; for (int e = 0; e < EdgeGainV.Len(); e++) { const TIntPr& Edge = EdgeGainV[e].Val2; if (Graph->IsEdge(Edge.Val1, Edge.Val2)) { continue; } // if edge was already included in the graph const double EProb = GetAllCascProb(Edge.Val1, Edge.Val2); EdgeGainV[e].Val1 = EProb; // update marginal gain if (BestGain < EProb) { BestGain = EProb; BestGainIndex = e; BestE = Edge; } // if we only update one weight, we don't need to sort the list attempts++; // keep track of zero edges after sorting once the full list if (!Graph->IsEdge(Edge.Val1, Edge.Val2) && Graph->GetEdges() > 1) { if (EProb == 0) EdgeZero.Add(e); } // lazy evaluation if (e+1 == EdgeGainV.Len() || BestGain >= EdgeGainV[e+1].Val1) { CurProb += BestGain; if (BestGain == 0) return TIntPr(-1, -1); EdgeGainV.Del(BestGainIndex); // we know the edges in 0 will be in sorted order, so we start from the biggest for (int i=EdgeZero.Len()-1; i>=0; i--) { if (EdgeZero[i] > BestGainIndex) EdgeGainV.Del(EdgeZero[i]-1); else EdgeGainV.Del(EdgeZero[i]); } if (EdgeZero.Len() > 2) { attempts -= (EdgeZero.Len()-1); } msort = (attempts > 1); LastGain = BestGain; return BestE; } } printf("Edges exhausted!\n"); return TIntPr(-1, -1); }
// Test node, edge attribute functionality TEST(TCrossNet, ManipulateNodesEdgeAttributes) { int NNodes = 1000; int NEdges = 1000; // const char *FName = "demo.graph.dat"; TCrossNet Graph; TCrossNet Graph1; int i; int x, y; bool t; Graph = TCrossNet(); t = Graph.GetEdges() == 0; // create the edges for (i = NEdges - 1; i >= 0; i--) { x = (long) (drand48() * NNodes); y = (long) (drand48() * NNodes); Graph.AddEdge(x, y, i); } // create attributes and fill all nodes TStr attr1 = "str"; TStr attr2 = "int"; TStr attr3 = "float"; TStr attr4 = "default"; // Test vertical int iterator for edge Graph.AddIntAttrDatE(3, 3*2, attr2); Graph.AddIntAttrDatE(55, 55*2, attr2); Graph.AddIntAttrDatE(705, 705*2, attr2); Graph.AddIntAttrDatE(905, 905*2, attr2); EXPECT_EQ(3*2, Graph.GetEAIntI(attr2, 3).GetDat()); EXPECT_EQ(55*2, Graph.GetEAIntI(attr2, 55).GetDat()); int EdgeId = 0; int DefEdges = 0; TVec<TInt> TAIntIV = TVec<TInt>(); for (TCrossNet::TAIntI EI = Graph.BegEAIntI(attr2); EI < Graph.EndEAIntI(attr2); EI++) { if (EI.GetDat() != TInt::Mn) { TAIntIV.Add(EI.GetDat()); EdgeId++; } else { DefEdges++; } } EXPECT_EQ(4, EdgeId); EXPECT_EQ(NEdges - 4, DefEdges); TAIntIV.Sort(); EXPECT_EQ(3*2, TAIntIV[0]); EXPECT_EQ(55*2, TAIntIV[1]); EXPECT_EQ(705*2, TAIntIV[2]); EXPECT_EQ(905*2, TAIntIV[3]); // Test vertical flt iterator for edge Graph.AddFltAttrE(attr3, 0.00); Graph.AddFltAttrDatE(5, 4.41, attr3); Graph.AddFltAttrDatE(50, 3.718, attr3); Graph.AddFltAttrDatE(300, 151.0, attr3); Graph.AddFltAttrDatE(653, 654, attr3); EXPECT_EQ(4.41, Graph.GetEAFltI(attr3, 5).GetDat()); EXPECT_EQ(3.718, Graph.GetEAFltI(attr3, 50).GetDat()); EdgeId = 0; DefEdges = 0; TVec<TFlt> TAFltIV = TVec<TFlt>(); for (TCrossNet::TAFltI EI = Graph.BegEAFltI(attr3); EI < Graph.EndEAFltI(attr3); EI++) { // Check if defaults are set to 0. if (EI.GetDat() != 0.00) { TAFltIV.Add(EI.GetDat()); EdgeId++; } else { DefEdges++; } } EXPECT_EQ(4, EdgeId); EXPECT_EQ(NEdges - 4, DefEdges); TAFltIV.Sort(); EXPECT_EQ(3.718, TAFltIV[0]); EXPECT_EQ(4.41, TAFltIV[1]); EXPECT_EQ(151.0, TAFltIV[2]); EXPECT_EQ(654.0, TAFltIV[3]); // Test vertical str iterator for edge Graph.AddStrAttrDatE(10, "abc", attr1); Graph.AddStrAttrDatE(20, "def", attr1); Graph.AddStrAttrDatE(400, "ghi", attr1); // this does not show since ""=null Graph.AddStrAttrDatE(455, "", attr1); EXPECT_EQ('c', Graph.GetEAStrI(attr1, 10).GetDat().LastCh()); EXPECT_EQ('f', Graph.GetEAStrI(attr1, 20).GetDat().LastCh()); EdgeId = 0; DefEdges = 0; TVec<TStr> TAStrIV = TVec<TStr>(); for (TCrossNet::TAStrI EI = Graph.BegEAStrI(attr1); EI < Graph.EndEAStrI(attr1); EI++) { if (EI.GetDat() != TStr::GetNullStr()) { TAStrIV.Add(EI.GetDat()); EdgeId++; } else { DefEdges++; } } EXPECT_EQ(3, EdgeId); EXPECT_EQ(NEdges - 3, DefEdges); TAStrIV.Sort(); // TODO(nkhadke): Fix hack to compare strings properly. This works for now. EXPECT_EQ('c', TAStrIV[0].LastCh()); EXPECT_EQ('f', TAStrIV[1].LastCh()); EXPECT_EQ('i', TAStrIV[2].LastCh()); // Test vertical iterator over many types (must skip default/deleted attr) int EId = 55; Graph.AddStrAttrDatE(EId, "aaa", attr1); Graph.AddIntAttrDatE(EId, 3*2, attr2); Graph.AddFltAttrDatE(EId, 3.41, attr3); Graph.AddStrAttrDatE(80, "dont appear", attr4); // should not show up TStrV EIdAttrName; Graph.AttrNameEI(EId, EIdAttrName); TInt AttrLen = EIdAttrName.Len(); EXPECT_EQ(3, AttrLen); Graph.DelAttrDatE(EId, attr2); Graph.AttrNameEI(EId, EIdAttrName); AttrLen = EIdAttrName.Len(); for (i = 0; i < AttrLen; i++) { if (TStr("int") == EIdAttrName[i]()) { // FAIL EXPECT_EQ(2,3); } } Graph.AddIntAttrDatE(EId, 3*2, attr2); Graph.DelAttrE(attr1); Graph.AttrNameEI(EId, EIdAttrName); AttrLen = EIdAttrName.Len(); for (i = 0; i < AttrLen; i++) { if (TStr("aaa") == EIdAttrName[i]()) { // FAIL EXPECT_EQ(2,3); } } TStrV EIdAttrValue; Graph.AttrValueEI(EId, EIdAttrValue); AttrLen = EIdAttrValue.Len(); for (i = 0; i < AttrLen; i++) { if (TStr("str") == EIdAttrValue[i]()) { // FAIL EXPECT_EQ(2,3); } } int expectedTotal = 0; for (i = 0; i <NEdges; i++) { Graph.AddIntAttrDatE(i, NEdges+i, attr2); EXPECT_EQ(NEdges+i, Graph.GetIntAttrDatE(i, attr2)); expectedTotal += NEdges+i; } // { // TFOut FOut(FName); // Graph.Save(FOut); // FOut.Flush(); // Graph.Clr(); // } }
// Test node, edge attribute functionality TEST(TNEANet, ManipulateNodesEdgeAttributes) { int NNodes = 1000; int NEdges = 1000; const char *FName = "demo.graph.dat"; PNEANet Graph; PNEANet Graph1; int i; int x, y; bool t; Graph = TNEANet::New(); t = Graph->Empty(); // create the nodes for (i = NNodes - 1; i >= 0; i--) { Graph->AddNode(i); } EXPECT_EQ(NNodes, Graph->GetNodes()); // create the edges for (i = NEdges - 1; i >= 0; i--) { x = (long) (drand48() * NNodes); y = (long) (drand48() * NNodes); Graph->AddEdge(x, y, i); } // create attributes and fill all nodes TStr attr1 = "str"; TStr attr2 = "int"; TStr attr3 = "float"; TStr attr4 = "default"; // Test vertical int iterator for node 3, 50, 700, 900 // Check if we can set defaults to 0 for Int data. Graph->AddIntAttrN(attr2, 0); Graph->AddIntAttrDatN(3, 3*2, attr2); Graph->AddIntAttrDatN(50, 50*2, attr2); Graph->AddIntAttrDatN(700, 700*2, attr2); Graph->AddIntAttrDatN(900, 900*2, attr2); EXPECT_EQ(3*2, Graph->GetNAIntI(attr2, 3).GetDat()); EXPECT_EQ(50*2, Graph->GetNAIntI(attr2, 50).GetDat()); int NodeId = 0; int DefNodes = 0; TVec<TInt> TAIntIV = TVec<TInt>(); for (TNEANet::TAIntI NI = Graph->BegNAIntI(attr2); NI < Graph->EndNAIntI(attr2); NI++) { if (NI.GetDat()() != 0) { TAIntIV.Add(NI.GetDat()); NodeId++; } else { DefNodes++; } } EXPECT_EQ(4, NodeId); EXPECT_EQ(NNodes - 4, DefNodes); TAIntIV.Sort(); EXPECT_EQ(3*2, TAIntIV[0]); EXPECT_EQ(50*2, TAIntIV[1]); EXPECT_EQ(700*2, TAIntIV[2]); EXPECT_EQ(900*2, TAIntIV[3]); // Test vertical flt iterator for node 3, 50, 700, 900 Graph->AddFltAttrDatN(5, 3.41, attr3); Graph->AddFltAttrDatN(50, 2.718, attr3); Graph->AddFltAttrDatN(300, 150.0, attr3); Graph->AddFltAttrDatN(653, 563, attr3); EXPECT_EQ(3.41, Graph->GetNAFltI(attr3, 5).GetDat()); EXPECT_EQ(2.718, Graph->GetNAFltI(attr3, 50).GetDat()); NodeId = 0; DefNodes = 0; TVec<TFlt> TAFltIV = TVec<TFlt>(); for (TNEANet::TAFltI NI = Graph->BegNAFltI(attr3); NI < Graph->EndNAFltI(attr3); NI++) { if (NI.GetDat() != TFlt::Mn) { NodeId++; TAFltIV.Add(NI.GetDat()); } else { DefNodes++; } } EXPECT_EQ(4, NodeId); EXPECT_EQ(NNodes - 4, DefNodes); TAFltIV.Sort(); EXPECT_EQ(2.718, TAFltIV[0]); EXPECT_EQ(3.41, TAFltIV[1]); EXPECT_EQ(150.0, TAFltIV[2]); EXPECT_EQ(563.0, TAFltIV[3]); // Test vertical str iterator for node 3, 50, 700, 900 Graph->AddStrAttrDatN(10, "abc", attr1); Graph->AddStrAttrDatN(20, "def", attr1); Graph->AddStrAttrDatN(400, "ghi", attr1); // this does not show since ""=null Graph->AddStrAttrDatN(455, "", attr1); EXPECT_EQ('c', Graph->GetNAStrI(attr1, 10).GetDat().LastCh()); EXPECT_EQ('f', Graph->GetNAStrI(attr1, 20).GetDat().LastCh()); NodeId = 0; DefNodes = 0; TVec<TStr> TAStrIV = TVec<TStr>(); for (TNEANet::TAStrI NI = Graph->BegNAStrI(attr1); NI < Graph->EndNAStrI(attr1); NI++) { if (NI.GetDat() != TStr::GetNullStr()) { NodeId++; TAStrIV.Add(NI.GetDat()); } else { DefNodes++; } } EXPECT_EQ(3, NodeId); EXPECT_EQ(NNodes - 3, DefNodes); TAStrIV.Sort(); // TODO(nkhadke): Fix hack to compare strings properly. This works for now. EXPECT_EQ('c', TAStrIV[0].LastCh()); EXPECT_EQ('f', TAStrIV[1].LastCh()); EXPECT_EQ('i', TAStrIV[2].LastCh()); // Test vertical iterator over many types (must skip default/deleted attr) int NId = 55; Graph->AddStrAttrDatN(NId, "aaa", attr1); Graph->AddIntAttrDatN(NId, 3*2, attr2); Graph->AddFltAttrDatN(NId, 3.41, attr3); Graph->AddStrAttrDatN(80, "dont appear", attr4); // should not show up TStrV NIdAttrName; Graph->AttrNameNI(NId, NIdAttrName); int AttrLen = NIdAttrName.Len(); NodeId = 0; DefNodes = 0; EXPECT_EQ(3, AttrLen); Graph->DelAttrDatN(NId, attr2); Graph->AttrNameNI(NId, NIdAttrName); AttrLen = NIdAttrName.Len(); for (i = 0; i < AttrLen; i++) { if (TStr("int") == NIdAttrName[i]()) { // FAIL EXPECT_EQ(1,2); } } EXPECT_EQ(2, AttrLen); Graph->AddIntAttrDatN(NId, 3*2, attr2); Graph->DelAttrN(attr1); Graph->AttrNameNI(NId, NIdAttrName); AttrLen = NIdAttrName.Len(); for (i = 0; i < AttrLen; i++) { if (TStr("str") == NIdAttrName[i]()) { // FAIL EXPECT_EQ(1,2); } } EXPECT_EQ(2, AttrLen); TStrV NIdAttrValue; Graph->AttrValueNI(NId, NIdAttrValue); AttrLen = NIdAttrValue.Len(); for (i = 0; i < AttrLen; i++) { if (TStr("str") == NIdAttrValue[i]()) { // FAIL EXPECT_EQ(1,2); } } int expectedTotal = 0; for (i = 0; i <NNodes; i++) { Graph->AddIntAttrDatN(i, NNodes+i, attr2); EXPECT_EQ(NNodes+i, Graph->GetIntAttrDatN(i, attr2)); expectedTotal += NNodes+i; } { TFOut FOut(FName); Graph->Save(FOut); FOut.Flush(); } { TFIn FIn(FName); Graph1 = TNEANet::Load(FIn); } int total = 0; for (TNEANet::TAIntI NI = Graph1->BegNAIntI(attr2); NI < Graph1->EndNAIntI(attr2); NI++) { total += NI.GetDat(); } ASSERT_EQ(expectedTotal, total); Graph1->Clr(); // Test vertical int iterator for edge Graph->AddIntAttrDatE(3, 3*2, attr2); Graph->AddIntAttrDatE(55, 55*2, attr2); Graph->AddIntAttrDatE(705, 705*2, attr2); Graph->AddIntAttrDatE(905, 905*2, attr2); EXPECT_EQ(3*2, Graph->GetEAIntI(attr2, 3).GetDat()); EXPECT_EQ(55*2, Graph->GetEAIntI(attr2, 55).GetDat()); int EdgeId = 0; int DefEdges = 0; TAIntIV.Clr(); for (TNEANet::TAIntI EI = Graph->BegEAIntI(attr2); EI < Graph->EndEAIntI(attr2); EI++) { if (EI.GetDat() != TInt::Mn) { TAIntIV.Add(EI.GetDat()); EdgeId++; } else { DefEdges++; } } EXPECT_EQ(4, EdgeId); EXPECT_EQ(NEdges - 4, DefEdges); TAIntIV.Sort(); EXPECT_EQ(3*2, TAIntIV[0]); EXPECT_EQ(55*2, TAIntIV[1]); EXPECT_EQ(705*2, TAIntIV[2]); EXPECT_EQ(905*2, TAIntIV[3]); // Test vertical flt iterator for edge Graph->AddFltAttrE(attr3, 0.00); Graph->AddFltAttrDatE(5, 4.41, attr3); Graph->AddFltAttrDatE(50, 3.718, attr3); Graph->AddFltAttrDatE(300, 151.0, attr3); Graph->AddFltAttrDatE(653, 654, attr3); EXPECT_EQ(4.41, Graph->GetEAFltI(attr3, 5).GetDat()); EXPECT_EQ(3.718, Graph->GetEAFltI(attr3, 50).GetDat()); EdgeId = 0; DefEdges = 0; TAFltIV.Clr(); for (TNEANet::TAFltI EI = Graph->BegEAFltI(attr3); EI < Graph->EndEAFltI(attr3); EI++) { // Check if defaults are set to 0. if (EI.GetDat() != 0.00) { TAFltIV.Add(EI.GetDat()); EdgeId++; } else { DefEdges++; } } EXPECT_EQ(4, EdgeId); EXPECT_EQ(NEdges - 4, DefEdges); TAFltIV.Sort(); EXPECT_EQ(3.718, TAFltIV[0]); EXPECT_EQ(4.41, TAFltIV[1]); EXPECT_EQ(151.0, TAFltIV[2]); EXPECT_EQ(654.0, TAFltIV[3]); // Test vertical str iterator for edge Graph->AddStrAttrDatE(10, "abc", attr1); Graph->AddStrAttrDatE(20, "def", attr1); Graph->AddStrAttrDatE(400, "ghi", attr1); // this does not show since ""=null Graph->AddStrAttrDatE(455, "", attr1); EXPECT_EQ('c', Graph->GetEAStrI(attr1, 10).GetDat().LastCh()); EXPECT_EQ('f', Graph->GetEAStrI(attr1, 20).GetDat().LastCh()); EdgeId = 0; DefEdges = 0; TAStrIV.Clr(); for (TNEANet::TAStrI EI = Graph->BegEAStrI(attr1); EI < Graph->EndEAStrI(attr1); EI++) { if (EI.GetDat() != TStr::GetNullStr()) { TAStrIV.Add(EI.GetDat()); EdgeId++; } else { DefEdges++; } } EXPECT_EQ(3, EdgeId); EXPECT_EQ(NEdges - 3, DefEdges); TAStrIV.Sort(); // TODO(nkhadke): Fix hack to compare strings properly. This works for now. EXPECT_EQ('c', TAStrIV[0].LastCh()); EXPECT_EQ('f', TAStrIV[1].LastCh()); EXPECT_EQ('i', TAStrIV[2].LastCh()); // Test vertical iterator over many types (must skip default/deleted attr) int EId = 55; Graph->AddStrAttrDatE(EId, "aaa", attr1); Graph->AddIntAttrDatE(EId, 3*2, attr2); Graph->AddFltAttrDatE(EId, 3.41, attr3); Graph->AddStrAttrDatE(80, "dont appear", attr4); // should not show up TStrV EIdAttrName; Graph->AttrNameEI(EId, EIdAttrName); AttrLen = EIdAttrName.Len(); EXPECT_EQ(3, AttrLen); Graph->DelAttrDatE(EId, attr2); Graph->AttrNameEI(EId, EIdAttrName); AttrLen = EIdAttrName.Len(); for (i = 0; i < AttrLen; i++) { if (TStr("int") == EIdAttrName[i]()) { // FAIL EXPECT_EQ(2,3); } } Graph->AddIntAttrDatE(EId, 3*2, attr2); Graph->DelAttrE(attr1); Graph->AttrNameEI(EId, EIdAttrName); AttrLen = EIdAttrName.Len(); for (i = 0; i < AttrLen; i++) { if (TStr("aaa") == EIdAttrName[i]()) { // FAIL EXPECT_EQ(2,3); } } TStrV EIdAttrValue; Graph->AttrValueEI(EId, EIdAttrValue); AttrLen = EIdAttrValue.Len(); for (i = 0; i < AttrLen; i++) { if (TStr("str") == EIdAttrValue[i]()) { // FAIL EXPECT_EQ(2,3); } } expectedTotal = 0; for (i = 0; i <NEdges; i++) { Graph->AddIntAttrDatE(i, NEdges+i, attr2); EXPECT_EQ(NEdges+i, Graph->GetIntAttrDatE(i, attr2)); expectedTotal += NEdges+i; } { TFOut FOut(FName); Graph->Save(FOut); FOut.Flush(); Graph->Clr(); } { TFIn FIn(FName); Graph1 = TNEANet::Load(FIn); } total = 0; for (TNEANet::TAIntI EI = Graph1->BegNAIntI(attr2); EI < Graph1->EndNAIntI(attr2); EI++) { total += EI.GetDat(); } EXPECT_EQ(expectedTotal, total); //Graph1->Dump(); Graph1->Clr(); }