/*************************************************************************** * Copyright (c) 2023 Ondsel, Inc. * * * * This file is part of OndselSolver. * * * * See LICENSE file for details about copyright. * ***************************************************************************/ #pragma once #include #include #include "SparseVector.h" #include "FullRow.h" namespace MbD { template class SparseRow; template using SpRowsptr = std::shared_ptr>; using SpRowDsptr = std::shared_ptr>; template class SparseRow : public SparseVector { public: SparseRow() {} SparseRow(size_t n) : SparseVector(n) {} SparseRow(std::initializer_list> list) : SparseVector{ list } {} SparseRow(std::initializer_list> list) : SparseVector{ list } {} SpRowDsptr timesconditionedWithTol(double scaling, double tol); SpRowDsptr conditionedWithTol(double tol); void atiplusFullRow(size_t j, FRowsptr fullRow); void atiminusFullRow(size_t j, FRowsptr fullRow); void atiplusFullRowtimes(size_t j, FRowsptr fullRow, double factor); T timesFullColumn(FColsptr fullCol); SpRowsptr plusSparseRow(SpRowsptr spMat); SpRowsptr clonesptr(); }; template<> inline SpRowDsptr SparseRow::timesconditionedWithTol(double scaling, double tol) { auto answer = std::make_shared>(this->numberOfElements()); for (auto const& keyValue : *this) { auto val = keyValue.second * scaling; if (std::abs(val) >= tol) (*answer)[keyValue.first] = val; } return answer; } template<> inline SpRowDsptr SparseRow::conditionedWithTol(double tol) { auto answer = std::make_shared>(this->numberOfElements()); for (auto const& keyValue : *this) { auto val = keyValue.second; if (std::abs(val) >= tol) (*answer)[keyValue.first] = val; } return answer; } template inline void SparseRow::atiplusFullRow(size_t j, FRowsptr fullRow) { for (size_t jj = 0; jj < fullRow->size(); jj++) { (*this)[j + jj] += fullRow->at(jj); } } template inline void SparseRow::atiminusFullRow(size_t j, FRowsptr fullRow) { for (size_t jj = 0; jj < fullRow->size(); jj++) { (*this)[j + jj] -= fullRow->at(jj); } } template inline void SparseRow::atiplusFullRowtimes(size_t j, FRowsptr fullRow, double factor) { for (size_t jj = 0; jj < fullRow->size(); jj++) { (*this)[j + jj] += fullRow->at(jj) * factor; } } template inline T SparseRow::timesFullColumn(FColsptr fullCol) { T sum = 0.0; for (auto const& keyValue : *this) { sum += fullCol->at(keyValue.first) * keyValue.second; } return sum; } template inline SpRowsptr SparseRow::plusSparseRow(SpRowsptr spRow) { auto answer = clonesptr(); for (auto const& keyValue : *spRow) { auto key = keyValue.first; auto val = keyValue.second; if (answer->find(key) == answer->end()) { (*answer)[key] = val; } else { (*answer)[key] = val + answer->at(key); } } return answer; } template inline std::shared_ptr> SparseRow::clonesptr() { return std::make_shared>(*this); } }