Program Listing for File SparseAccumulator.hpp

Return to documentation for file (include/networkit/algebraic/SparseAccumulator.hpp)

/*
 * SparseAccumulator.hpp
 *
 *  Created on: 14.05.2014
 *      Author: Michael Wegner (michael.wegner@student.kit.edu)
 */

#ifndef NETWORKIT_ALGEBRAIC_SPARSE_ACCUMULATOR_HPP_
#define NETWORKIT_ALGEBRAIC_SPARSE_ACCUMULATOR_HPP_

#include <algorithm>
#include <cassert>
#include <vector>

#include <networkit/Globals.hpp>

namespace NetworKit {

class SparseAccumulator final {
private:
    count row;

    std::vector<double> values; // w

    std::vector<count> occupied; // b

    std::vector<index> indices; // LS

public:
    SparseAccumulator(count size) : row(1), values(size), occupied(size, 0) {}

    void scatter(double value, index pos) {
        if (occupied[pos] < row) {
            values[pos] = value;
            occupied[pos] = row;
            indices.push_back(pos);
        } else {
            values[pos] += value;
        }
    }

    template <typename L>
    void scatter(double value, index pos, L &handle) {
        assert(pos < values.size());

        if (occupied[pos] < row) {
            values[pos] = value;
            occupied[pos] = row;
            indices.push_back(pos);
        } else {
            values[pos] = handle(values[pos], value);
        }
    }

    template <typename L>
    count gather(L handle) {
        count nonZeros = 0;
        std::sort(indices.begin(), indices.end());
        for (index idx : indices) {
            handle(row - 1, idx, values[idx]);
            ++nonZeros;
        }

        return nonZeros;
    }

    void increaseRow() {
        ++row;
        indices.clear();
    }
};

} /* namespace NetworKit */

#endif // NETWORKIT_ALGEBRAIC_SPARSE_ACCUMULATOR_HPP_