/*
 * LaplacianCentrality.cpp
 *
 *  Created on: 08.03.2018
 *      Author: Kolja Esders
 */

#include <networkit/centrality/LaplacianCentrality.hpp>

namespace NetworKit {

LaplacianCentrality::LaplacianCentrality(const Graph& G, bool normalized): Centrality(G, normalized) {
}

void LaplacianCentrality::run() {
    scoreData = std::vector<double>(G.upperNodeIdBound(), 0.0);
    double totalLaplacianEnergy = 0.0;

    G.parallelForNodes([&](node u) {
        count degreeU = G.weightedDegree(u);
        double energyLossOnNodeDrop = degreeU * degreeU;
#pragma omp atomic
        totalLaplacianEnergy += degreeU * degreeU;

        G.forNeighborsOf(u, [&](node v, edgeweight ew) {
            energyLossOnNodeDrop += ew * (ew + 2 * G.weightedDegree(v));
#pragma omp atomic
            totalLaplacianEnergy += ew * ew;
        });

        scoreData[u] = energyLossOnNodeDrop;
    });

    if (!normalized) {
        hasRun = true;
        return;
    }

    G.parallelForNodes([&](node u) {
        scoreData[u] /= totalLaplacianEnergy;
    });

    hasRun = true;
}

} /* namespace NetworKit */
