void removeMatrixRow(int row, MatDoub &out) { int dummy = -1000; Rh.resize(Ri.nrows(),Ri.nrows()); Rh = Ri; for(int i=0; i<Rh.nrows(); i++) { Rh[row][i] = dummy; Rh[i][row] = dummy; } datain = Rh.getMatrixArray(); data [Rh.nrows()*Rh.nrows()]; int k=0; for(int i=0; i < Rh.nrows()*Rh.nrows(); i++) { double ele = datain[i]; if(ele != dummy) data[k++] = ele; } out = MatDoub( out.nrows(), out.nrows(), data ); }
void dump_nrmat( MatDoub &m ) { for( int r=0; r<m.nrows(); r++ ) { for( int c=0; c<m.ncols(); c++ ) { printf( "%+3.2le ", m[r][c] ); } printf( "\n" ); } }
void removeMatrixRow( MatDoub &out ) { int dummy = -1000; datain = Ri.getMatrixArray(); data [Ri.nrows()*Ri.nrows()]; int k=0; for(int i=0; i < Ri.nrows()*Ri.ncols(); i++) { double ele = datain[i]; if(ele != dummy) data[k++] = ele; } out = MatDoub( out.nrows(), out.nrows(), data ); }
/* Utility method used by Geodesic and RandomWalk algorithms to set-up the Modularity and Laplacian matrices. */ void setupMatrices() { //--- Matrix size int N = R.nrows(); //--- 2*m two_m = elist.size(); //--- _norm _norm = 1.0/(2.0*two_m); for(int i=0; i<N; i++) { C[i] = 0; for(int j=0; j<N; j++) { R[i][j] = 0.0; A[i][j] = 0.0; } } //--- Setup Matrices //--- Store the current community each vertex belongs too for(int i=0; i<N; i++) { R[i][i] = n[i+1].getDegree(); C[i] = n[i+1].c; } //--- The Adjacency matrix, A for(int i=0; i<elist.size(); i++) { int ind_i = elist[i].so -1; int ind_j = elist[i].si -1; if( ind_i == ind_j || ind_j == ind_i ) A[ind_i][ind_j] = 1.0 * elist[i].Globalwe; else { A[ind_i][ind_j] = 1.0 * elist[i].Globalwe; A[ind_j][ind_i] = 1.0 * elist[i].Globalwe; } } for(int i=0; i<N; i++) { for(int j=0; j<N; j++) { R[i][j] = R[i][j] - A[i][j]; } } //--- The Modularity matrix, Bgi for(int i=1; i<n.size(); i++) { for(int j=1; j<n.size(); j++) { Bgi[i-1][j-1] = A[i-1][j-1] - (n[i].getDegree() * n[j].getDegree() * _norm); } } }
void addMatrixRow(MatDoub U, int row, MatDoub &out) { int dummy = -1000; for(int i=0; i<out.nrows(); i++) { out[i][row] = dummy; out[row][i] = dummy; } datain = U.getMatrixArray(); datainO = out.getMatrixArray(); int k = 0; data [out.nrows()*out.nrows()]; for(int i=0; i < out.nrows()*out.ncols(); i++) { if( datainO[i] == dummy ) data[i] = 0; else data[i] = datain[k++]; } out = MatDoub( out.nrows(), out.nrows(), data ); }
/* Utility method use by the RandomWalk algorithm to update the Adjacency and Laplacian matrices. */ void upDateMatrices() { for(int i=0; i<R.nrows(); i++) { C[i] = 0; for(int j=0; j<R.nrows(); j++) { R[i][j] = 0; } } //--- Setup Matrices //--- Store the current community each vertex belongs too for(int i=0; i<R.nrows(); i++) { R[i][i] = n[i+1].getDegree(); C[i] = n[i+1].c; } //--- Update the Adjacency matrix, A for(int i=0; i<elist.size(); i++) { if( elist[i].removed ) { int ind_i = elist[i].so -1; int ind_j = elist[i].si -1; //if edge has been removed, remove this entry //from A. A[ind_i][ind_j] = 0; A[ind_j][ind_i] = 0; } } //--- Update the Lapacian matrix, R for(int i=0; i<R.nrows(); i++) { for(int j=0; j<R.nrows(); j++) { R[i][j] = R[i][j] - A[i][j]; } } }
void copyNRMatToZMat( MatDoub &m, ZMat &z ) { // account for NR3 is rowmajor, ZMat is colmajor. int rows = m.nrows(); int cols = m.ncols(); if( z.rows != rows || z.cols != cols ) { z.alloc( rows, cols, zmatF64 ); } for( int r=0; r<rows; r++ ) { for( int c=0; c<cols; c++ ) { z.putD( r, c, m[r][c] ); } } }
void removeMatrixRow( MatDoub Unr, MatDoub &outnr ) { int dummy = -1000; datain = Unr.getMatrixArray(); data [outnr.nrows()*outnr.nrows()]; int k=0; for(int i=0; i < Unr.nrows()*Unr.nrows(); i++) { double ele = datain[i]; if(ele != dummy) data[k++] = ele; } outnr = MatDoub( outnr.nrows(), outnr.nrows(), data ); }
/* Utility method used by RandomWalk algorithm to resize the Graph Laplacian for each community, com, within the network. */ void getSubMatrix(int com, vector<node> &Nodes) { int dummy = -1000; int rows = 0; Rh.resize(R.nrows(), R.nrows()); Rh = R; //--- NR style for( int i=0; i< C.size(); i++) { if( C[i] == com ) Nodes.push_back(node(rows++,0.0,0.0)); else { for( int k=0; k<Rh.nrows(); k++) { Rh[i][k] = dummy; Rh[k][i] = dummy; } } } datain = Rh.getMatrixArray(); data [Rh.nrows()*Rh.nrows()]; int ind = 0; for(int i=0; i < Rh.nrows()*Rh.ncols(); i++) { double ele = datain[i]; if(ele != dummy) data[ind++] = ele; } Ri.resize(rows,rows); Ri = MatDoub( rows, rows, data ); }
/* Calculate the split of nodes belonging to the last group of nodes with negative eigenvector values. */ void splitN(MatDoub Bg, VecInt keys, int dummy, double tol) { cout << "> In splitN method... " << endl; int N = Bg.nrows(); MatDoub Bgii(N,N); MatDoub Bgiii(N,N); VecInt keysi_n (N); //--- Starting from the group Modularity matrix Bg, //--- resize matrices: Bgi, keysi_p, keysi_n, u and betai. Bgiii = Bg; int Ng = 0; for(int i=0; i<keys.size(); i++) { if(keys[i] != dummy) { Ng++; } else { for(int k=0; k<Bgiii.nrows(); k++) { Bgiii[i][k] = dummy; Bgiii[k][i] = dummy; } } } keysi_n.resize(Ng); VecInt keysi_p(Ng); int k=0; for(int i=0; i<keys.size(); i++) { if(keys[i] != dummy) keysi_n[k++] = keys[i]; } Bgii.resize(Ng,Ng); removeMatrixRow(Bgiii,Bgii); Bgi.resize(Bgii.nrows(),Bgii.nrows()); //--- Calculate the Modularity matrix Bgi for the new node group calculateB(Bgii, Bgi); u.resize(Ng,Ng); betai.resize(Ng); //--- Calculate eigenvectors, and values, from Bgi... calculateEigenVectors(); int ind = 0; findLeadingEigenVectors(ind); //--- Check that maximum eigenvalue is greater than the tolerance. cout << "> max EigenValue is " << betai[ind] << " with ind " << ind << endl; if(betai[ind] > tol ) { //--- set up the index vectors, si and SI, for the initial split maximiseIndexVectors(ind); double deltaQ_old = 0.0; double deltaQ_new = 0.0; int cp = 0; int cn = 0; //--- Calculate the Spectral Modularity deltaModularity(deltaQ_old); cout << "> Spectral Q: " << deltaQ_old << endl; double diff = fabs(deltaQ_old); int count = 0; //--- Fine tuning stage to maximum deltaModularity for the initial split while( diff > tol ) { modifySplit( tol, Ng ); deltaModularity(deltaQ_new); cout << "> Modified Q: " << deltaQ_new << endl; diff = fabs( deltaQ_new - deltaQ_old ); deltaQ_old = deltaQ_new; } //--- Keep recorded of maximum fine-tuned Modularity value. specQ += deltaQ_old; for(int i=0; i<Ng; i++) { si[i] = si[i]; if(si[i] > 0) cp++; else cn++; } if(cp < 1 || cn < 1) { cout << "> Stop splitting. " << endl; return; } int Ncomn = maxCommunity() + 1; int Ncomp = Ncomn + 1; cout << "> node list " << endl; for(int i=0; i<keysi_n.size(); i++) { if( si[i] < 0) { keysi_n[i] = keysi_n[i]; keysi_p[i] = dummy; n[(int)keysi_n[i]].c = Ncomn; cout << "> Node: " << keysi_n[i] << " c = " << n[(int)keysi_n[i]].c << endl; } else { keysi_p[i] = keysi_n[i]; keysi_n[i] = dummy; cout << "> Node: " << keysi_p[i] << " c = " << n[(int)keysi_p[i]].c << endl; } } //--- Recursively split the group of positive eigenvector nodes splitP(Bgii, keysi_p, dummy, tol); //--- Recursively split the group of negative eigenvector nodes splitN(Bgii, keysi_n, dummy, tol); } else { cout << "> Stop splitting. " << endl; return ; } }
/* Utility method used by the RandomWalk algorithm to invert the Graph Laplacian and accummulate the random-path contributions from each source-sink node pair, in accordance with [2] (see method declarations above). */ void calculateRandomWalk(int c, vector<node> Nodes) { queue<node> termNodes; for(int i=0; i<Nodes.size(); i++) termNodes.push(Nodes[i]); int N = Nodes.size(); S.resize(N,1); V.resize(N,1); T.resize(N,N); Rc.resize((N-1),(N-1)); Vi.resize(C.size(),1); //--- Remove arbitrary termination ('sink') state '0'. removeMatrixRow(0,Rc); //--- Invert Matrix. LUdcmp lu( Rc ); Ti.resize(Rc.nrows(),Rc.nrows()); lu.inverse( Ti ); for(int i=0; i< T.nrows(); i++) { for(int j=0; j< T.nrows(); j++) { T[i][j] = 0; } } //--- Add back arbitrary termination ('sink') state '0'. addMatrixRow(Ti,0,T); while ( !termNodes.empty() ) { node termNode = termNodes.front(); termNodes.pop(); for(int t=0; t< Nodes.size(); t++) { //--- Take the next start ('source') state. node startNode = Nodes[t]; if( startNode.k != termNode.k ) { for(int i=0; i<S.nrows(); i++) { S[i][0] = 0; V[i][0] = 0; Vi[i][0] = 0; } S[startNode.k][0] = 1; S[termNode.k][0] = -1; //--- V = T * S for(int i=0; i<T.nrows(); i++) { double sum = 0.0; for(int j=0; j<T.nrows(); j++) { sum += T[i][j] * S[j][0]; } V[i][0] = sum; } addMatrixRows(V, c, Vi); //--- Edge Betweenness, i.e. //--- the currents (potential differences) alone each edge! for(int i=0; i<elist.size(); i++) { if( !elist[i].removed ) { int Ni = elist[i].so-1; int Nj = elist[i].si-1; totallist[i+1].we += fabs(Vi[Ni][0] - Vi[Nj][0]); } }//elist }//Nodes }//startNodes } }