Files
solver/OndselSolver/SparseVector.h

120 lines
3.0 KiB
C++

/***************************************************************************
* Copyright (c) 2023 Ondsel, Inc. *
* *
* This file is part of OndselSolver. *
* *
* See LICENSE file for details about copyright. *
***************************************************************************/
#pragma once
#include <map>
#include <cmath>
#include <sstream>
namespace MbD {
template<typename T>
class SparseVector : public std::map<int, T>
{
public:
int n;
SparseVector() {}
SparseVector(int n) : std::map<int, T>(), n(n) {}
SparseVector(std::initializer_list<std::pair<const int, T>> list) : std::map<int, T>{ list } {}
SparseVector(std::initializer_list<std::initializer_list<T>> list) {
for (auto& pair : list) {
int i = 0;
int index;
T value;
for (auto& element : pair) {
if (i == 0) index = (int)std::round(element);
if (i == 1) value = element;
i++;
}
this->insert(std::pair<const int, double>(index, value));
}
}
double rootMeanSquare();
int numberOfElements();
double sumOfSquares();
void atiput(int i, T value);
void atiplusNumber(int i, double value);
void atiminusNumber(int i, double value);
void zeroSelf();
double maxMagnitude();
virtual std::ostream& printOn(std::ostream& s) const;
friend std::ostream& operator<<(std::ostream& s, const SparseVector& spVec)
{
return spVec.printOn(s);
}
};
template<typename T>
inline double SparseVector<T>::rootMeanSquare()
{
return std::sqrt(this->sumOfSquares() / this->numberOfElements());
}
template<typename T>
inline int SparseVector<T>::numberOfElements()
{
return n;
}
template<typename T>
inline double SparseVector<T>::sumOfSquares()
{
double sum = 0.0;
for (auto const& keyValue : *this)
{
sum += keyValue.second * keyValue.second;
}
return sum;
}
template<typename T>
inline void SparseVector<T>::atiput(int i, T value)
{
(*this)[i] = value;
}
template<>
inline void SparseVector<double>::atiplusNumber(int i, double value)
{
(*this)[i] += value;
}
template<typename T>
inline void SparseVector<T>::atiminusNumber(int i, double value)
{
(*this)[i] -= value;
}
template<>
inline void SparseVector<double>::zeroSelf()
{
this->clear();
}
template<typename T>
inline double SparseVector<T>::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<typename T>
inline std::ostream& SparseVector<T>::printOn(std::ostream& s) const
{
s << "{";
auto index = 0;
for (const auto& keyValue : *this) {
if (index > 0) s << ", ";
s << keyValue.first;
s << "->";
s << keyValue.second;
index++;
}
s << "}";
return s;
}
}