↰ Return to documentation for file (include/networkit/algebraic/Vector.hpp
)
/*
* Vector.hpp
*
* Created on: 12.03.2014
* Author: Michael Wegner (michael.wegner@student.kit.edu)
*/
#ifndef NETWORKIT_ALGEBRAIC_VECTOR_HPP_
#define NETWORKIT_ALGEBRAIC_VECTOR_HPP_
#include <cassert>
#include <cmath>
#include <iostream>
#include <numeric>
#include <stdexcept>
#include <vector>
#include <networkit/Globals.hpp>
#include <networkit/algebraic/AlgebraicGlobals.hpp>
namespace NetworKit {
// forward declaration of DynamicMatrix class
class DynamicMatrix;
class Vector final {
private:
std::vector<double> values;
bool transposed;
public:
Vector();
Vector(count dimension, double initialValue = 0, bool transpose = false);
Vector(const std::vector<double> &values, bool transpose = false);
Vector(const std::initializer_list<double> &list);
inline count getDimension() const { return values.size(); }
bool isTransposed() const;
Vector transpose() const;
double length() const;
double mean() const;
inline double &operator[](index idx) {
assert(idx < values.size());
return values[idx];
}
void fill(double val) { std::fill(values.begin(), values.end(), val); }
inline double operator[](index idx) const {
assert(idx < values.size());
return values[idx];
}
double &at(index idx) {
if (idx >= values.size()) {
throw std::runtime_error("index out of range");
} else {
return values[idx];
}
}
bool operator==(const Vector &other) const;
bool operator!=(const Vector &other) const;
template <class Matrix = DynamicMatrix>
static Matrix outerProduct(const Vector &v1, const Vector &v2);
static double innerProduct(const Vector &v1, const Vector &v2);
double operator*(const Vector &other) const;
template <typename Matrix = DynamicMatrix>
Vector operator*(const Matrix &matrix) const;
Vector operator*(double scalar) const;
/*
* Multiplies this vector with a scalar specified in @a scalar.
* @return Reference to this vector.
*/
Vector &operator*=(double scalar);
Vector operator/(double divisor) const;
Vector &operator/=(double divisor);
Vector operator+(const Vector &other) const;
Vector operator+(double value) const;
Vector &operator+=(const Vector &other);
Vector &operator+=(double value);
Vector operator-(const Vector &other) const;
Vector operator-(double value) const;
Vector &operator-=(const Vector &other);
Vector &operator-=(double value);
template <typename F>
void apply(F unaryElementFunction);
template <typename L>
void forElements(L handle);
template <typename L>
void forElements(L handle) const;
template <typename L>
void parallelForElements(L handle);
template <typename L>
void parallelForElements(L handle) const;
};
inline Vector operator*(double scalar, const Vector &v) {
return v.operator*(scalar);
}
template <class Matrix>
Matrix Vector::outerProduct(const Vector &v1, const Vector &v2) {
std::vector<Triplet> triplets;
for (index i = 0; i < v1.getDimension(); ++i) {
for (index j = 0; j < v2.getDimension(); ++j) {
double result = v1[i] * v2[j];
if (std::fabs(result) >= FLOAT_EPSILON) {
triplets.push_back({i, j, result});
}
}
}
return Matrix(v1.getDimension(), v2.getDimension(), triplets);
}
template <class Matrix>
Vector Vector::operator*(const Matrix &matrix) const {
assert(isTransposed()); // vector must be of the form 1xn
assert(getDimension() == matrix.numberOfRows()); // dimensions of vector and matrix must match
Vector result(matrix.numberOfColumns(), 0.0, true);
#pragma omp parallel for
for (omp_index k = 0; k < static_cast<omp_index>(matrix.numberOfColumns()); ++k) {
Vector column = matrix.column(k);
result[k] = (*this) * column;
}
return result;
}
template <typename F>
void Vector::apply(F unaryElementFunction) {
#pragma omp parallel for
for (omp_index i = 0; i < static_cast<omp_index>(getDimension()); ++i) {
values[i] = unaryElementFunction(values[i]);
}
}
template <typename L>
inline void Vector::forElements(L handle) {
for (uint64_t i = 0; i < getDimension(); ++i) {
handle(values[i]);
}
}
template <typename L>
inline void Vector::forElements(L handle) const {
for (uint64_t i = 0; i < getDimension(); ++i) {
handle(values[i]);
}
}
template <typename L>
inline void Vector::parallelForElements(L handle) {
#pragma omp parallel for
for (omp_index i = 0; i < static_cast<omp_index>(getDimension()); ++i) {
handle(i, values[i]);
}
}
template <typename L>
inline void Vector::parallelForElements(L handle) const {
#pragma omp parallel for
for (omp_index i = 0; i < static_cast<omp_index>(getDimension()); ++i) {
handle(i, values[i]);
}
}
// print functions for test debugging / output. Prints Vector as [0, 1, 2, 3, 4]
inline std::ostream &operator<<(std::ostream &os, const Vector &vec) {
os << "[";
for (index i = 0; i < vec.getDimension(); i++) {
if (i != 0)
os << ", ";
os << vec[i];
}
os << "]";
return os;
}
} /* namespace NetworKit */
#endif // NETWORKIT_ALGEBRAIC_VECTOR_HPP_