/*************************************************************************** * Copyright (c) 2023 Ondsel, Inc. * * * * This file is part of OndselSolver. * * * * See LICENSE file for details about copyright. * ***************************************************************************/ #pragma once #include #include #include #include namespace MbD { template class SparseVector : public std::map { public: size_t n; SparseVector() {} SparseVector(size_t n) : std::map(), n(n) {} SparseVector(std::initializer_list> list) : std::map{ list } {} SparseVector(std::initializer_list> list) { for (auto& pair : list) { size_t i = 0; size_t index; T value; for (auto& element : pair) { if (i == 0) index = std::round(element); if (i == 1) value = element; i++; } this->insert(std::pair(index, value)); } } virtual ~SparseVector() {} double rootMeanSquare(); size_t numberOfElements(); double sumOfSquares(); void atiput(size_t i, T value); void atiplusNumber(size_t i, double value); void atiminusNumber(size_t i, double value); void zeroSelf(); double maxMagnitude(); void magnifySelf(T factor); virtual std::ostream& printOn(std::ostream& s) const; friend std::ostream& operator<<(std::ostream& s, const SparseVector& spVec) { return spVec.printOn(s); } }; template inline double SparseVector::rootMeanSquare() { return std::sqrt(this->sumOfSquares() / this->numberOfElements()); } template inline size_t SparseVector::numberOfElements() { return n; } template inline double SparseVector::sumOfSquares() { double sum = 0.0; for (auto const& keyValue : *this) { sum += keyValue.second * keyValue.second; } return sum; } template inline void SparseVector::atiput(size_t i, T value) { (*this)[i] = value; } template<> inline void SparseVector::atiplusNumber(size_t i, double value) { (*this)[i] += value; } template inline void SparseVector::atiminusNumber(size_t i, double value) { (*this)[i] -= value; } template<> inline void SparseVector::zeroSelf() { this->clear(); } template inline double SparseVector::maxMagnitude() { double max = 0.0; for (const auto& keyValue : *this) { auto val = keyValue.second; if (val < 0.0) val = -val; if (max < val) max = val; } return max; } template inline void SparseVector::magnifySelf(T factor) { for (const auto& keyValue : *this) { auto key = keyValue.first; auto val = keyValue.second; val *= factor; this->at(key) = val; } } template inline std::ostream& SparseVector::printOn(std::ostream& s) const { std::stringstream ss; ss << std::setprecision(std::numeric_limits::max_digits10); ss << "{" << std::endl; auto index = 0; for (const auto& keyValue : *this) { if (index > 0) ss << ", " << std::endl; ss << keyValue.first; ss << "->"; ss << keyValue.second; index++; } ss << std::endl << "}"; s << ss.str(); return s; } }