Eigen::MatrixXd localWeighting( const Eigen::MatrixXd &W, bool isFull, bool isSymmetric) { int n = W.rows(); double Ls = (W.count()-n)/2; //count number of edges of the graph Eigen::MatrixXd C = Eigen::MatrixXd::Zero(n,n); double Ws = 0.5*W.sum(); Eigen::VectorXd D = W.colwise().sum(); if (isFull) { if (isSymmetric) { computeC_symmetric_full(const_cast<Eigen::MatrixXd &>(W),C,D,n); } else { // this is a trick to ensure vectorizatoin and no cache misses! some tranpositions have to be made though const_cast<Eigen::MatrixXd &>(W).transposeInPlace(); computeC_symmetric_full(const_cast<Eigen::MatrixXd &>(W),C,D,n); const_cast<Eigen::MatrixXd &>(W).transposeInPlace(); C.transposeInPlace(); // the original code use vertical access to rows, but is slower //compute_C_asymmetric_full(const_cast<Eigen::MatrixXd &>(W),C,D,n); } } else { if (isSymmetric) { computeC_symmetric_sparse(const_cast<Eigen::MatrixXd &>(W),C,D,n); } else { compute_C_asymmetric_sparse(const_cast<Eigen::MatrixXd &>(W),C,D,n); } } Eigen::MatrixXd G = ((Ls/Ws)*W).cwiseProduct(C); Eigen::VectorXd DG = G.colwise().sum(); for (int i=0; i<n; i++) { G.row(i)/=DG(i); } return G; }