#pragma once #include #include #include #include #include #include namespace Gudhi_laplacian { template class Sparse_vector { public: Sparse_vector() : compressed(true), data() { static_assert(std::is_arithmetic::value, "Only arithmetic types are supported."); } // Default destructor. // Default copy-constructor. // Default assignment operator. // Default moves. void compress() { if (compressed) return; std::vector > tmp(data); data.clear(); std::sort(tmp.begin(), tmp.end()); for (auto it = tmp.cbegin(); it != tmp.cend(); ++it) { if (data.empty()) { if (it->second != T()) { data.push_back(*it); } } else if (it->first == data.back().first) { T x = data.back().second + it->second; if (x == T()) { data.pop_back(); } else { data.back().second = x; } } else if (it->second != T()) { data.push_back(*it); } } compressed = true; } inline void add(unsigned int i, T x) { data.push_back(std::make_pair(i, x)); compressed = false; } static std::vector > transpose(const std::vector > & x, unsigned int n) { unsigned int m = x.size(); std::vector > ret(n); for (unsigned int i = 0; i < m; ++i) { const Sparse_vector & a = x[i]; for (auto it = a.cbegin(); it != a.cend(); ++it) { assert(it->first < n); ret[it->first].data.push_back(std::make_pair(i, it->second)); // Avoid add to keep compressed = true. } } return ret; } inline const T & operator[](typename std::vector >::size_type i) { std::cerr << "UNTESTED FUNCTION" << std::endl; assert(compressed); auto it = std::lower_bound(data.cbegin(), data.cend(), std::make_pair(i, T()), [](const std::pair & x, const std::pair & y) { return x.first < y.first; }); if (it == data.cend() || it->first != i) return T(); else return it->second; } inline typename std::vector >::size_type size() const { return data.size(); } inline typename std::vector >::size_type nnz() const { return data.size(); } using Const_iterator = typename std::vector >::const_iterator; inline Const_iterator cbegin() const { return data.cbegin(); } inline Const_iterator cend() const { return data.cend(); } inline Const_iterator begin() const { return data.cbegin(); } inline Const_iterator end() const { return data.cend(); } private: bool compressed; std::vector > data; }; }