/*************************************************************************** * Copyright (c) 2023 Ondsel, Inc. * * * * This file is part of OndselSolver. * * * * See LICENSE file for details about copyright. * ***************************************************************************/ #pragma once #include #include "RowTypeMatrix.h" #include "SparseRow.h" #include "DiagonalMatrix.h" #include "FullMatrix.h" namespace MbD { template class SparseMatrix; using SpMatDsptr = std::shared_ptr>; template using SpMatsptr = std::shared_ptr>; class GESpMatParPvPrecise; template class SparseMatrix : public RowTypeMatrix> { public: SparseMatrix(size_t m) : RowTypeMatrix>(m) { } SparseMatrix(size_t m, size_t n) { for (size_t i = 0; i < m; i++) { auto row = std::make_shared>(n); this->push_back(row); } } SparseMatrix(std::initializer_list>> list2D) { for (auto& rowList : list2D) { auto row = std::make_shared>(rowList); this->push_back(row); } } void atiput(size_t i, SpRowsptr spRow); void atijplusDiagonalMatrix(size_t i, size_t j, DiagMatDsptr diagMat); void atijminusDiagonalMatrix(size_t i, size_t j, DiagMatDsptr diagMat); double sumOfSquares() override; void zeroSelf() override; void atijplusFullRow(size_t i, size_t j, FRowsptr fullRow); void atijplusFullColumn(size_t i, size_t j, FColsptr fullCol); void atijplusFullMatrix(size_t i, size_t j, FMatDsptr fullMat); void atijminusFullMatrix(size_t i, size_t j, FMatDsptr fullMat); void atijplusTransposeFullMatrix(size_t i, size_t j, FMatDsptr fullMat); void atijplusFullMatrixtimes(size_t i, size_t j, FMatDsptr fullMat, T factor); void atijminusFullColumn(size_t i, size_t j, FColDsptr fullCol); void atijminusTransposeFullMatrix(size_t i, size_t j, FMatDsptr fullMat); void atijplusNumber(size_t i, size_t j, double value); void atijminusNumber(size_t i, size_t j, double value); void atijput(size_t i, size_t j, T value); double maxMagnitude() override; FColsptr timesFullColumn(FColsptr fullCol); SpMatsptr plusSparseMatrix(SpMatsptr spMat); std::shared_ptr> clonesptr(); void magnifySelf(T factor); std::ostream& printOn(std::ostream& s) const override; }; template inline void SparseMatrix::atiput(size_t i, SpRowsptr spRow) { this->at(i) = spRow; } template inline void SparseMatrix::atijplusDiagonalMatrix(size_t i, size_t j, DiagMatDsptr diagMat) { auto n = diagMat->nrow(); for (size_t ii = 0; ii < n; ii++) { this->atijplusNumber(i + ii, j + ii, diagMat->at(ii)); } } template<> inline void SparseMatrix::atijminusDiagonalMatrix(size_t i1, size_t j1, DiagMatDsptr diagMat) { auto n = diagMat->nrow(); for (size_t ii = 0; ii < n; ii++) { this->atijminusNumber(i1 + ii, j1 + ii, diagMat->at(ii)); } } template inline double SparseMatrix::sumOfSquares() { double sum = 0.0; for (size_t i = 0; i < this->size(); i++) { sum += this->at(i)->sumOfSquares(); } return sum; } template<> inline void SparseMatrix::zeroSelf() { for (size_t i = 0; i < this->size(); i++) { this->at(i)->zeroSelf(); } } template inline void SparseMatrix::atijplusFullRow(size_t i, size_t j, FRowsptr fullRow) { this->at(i)->atiplusFullRow(j, fullRow); } template inline void SparseMatrix::atijplusFullColumn(size_t i, size_t j, FColsptr fullCol) { for (size_t ii = 0; ii < fullCol->size(); ii++) { this->atijplusNumber(i + ii, j, fullCol->at(ii)); } } template inline void SparseMatrix::atijminusFullColumn(size_t i, size_t j, FColDsptr fullCol) { for (size_t ii = 0; ii < fullCol->size(); ii++) { this->atijminusNumber(i + ii, j, fullCol->at(ii)); } } template inline void SparseMatrix::atijplusFullMatrix(size_t i, size_t j, FMatDsptr fullMat) { for (size_t ii = 0; ii < fullMat->nrow(); ii++) { this->at(i + ii)->atiplusFullRow(j, fullMat->at(ii)); } } template inline void SparseMatrix::atijminusFullMatrix(size_t i, size_t j, FMatDsptr fullMat) { for (size_t ii = 0; ii < fullMat->nrow(); ii++) { this->at(i + ii)->atiminusFullRow(j, fullMat->at(ii)); } } template inline void SparseMatrix::atijplusTransposeFullMatrix(size_t i, size_t j, FMatDsptr fullMat) { for (size_t ii = 0; ii < fullMat->nrow(); ii++) { this->atijplusFullColumn(i, j + ii, fullMat->at(ii)->transpose()); } } template inline void SparseMatrix::atijminusTransposeFullMatrix(size_t i, size_t j, FMatDsptr fullMat) { for (size_t ii = 0; ii < fullMat->nrow(); ii++) { this->atijminusFullColumn(i, j + ii, fullMat->at(ii)->transpose()); } } template inline void SparseMatrix::atijplusFullMatrixtimes(size_t i, size_t j, FMatDsptr fullMat, T factor) { for (size_t ii = 0; ii < fullMat->nrow(); ii++) { this->at(i + ii)->atiplusFullRowtimes(j, fullMat->at(ii), factor); } } template inline void SparseMatrix::atijplusNumber(size_t i, size_t j, double value) { this->at(i)->atiplusNumber(j, value); } template inline void SparseMatrix::atijminusNumber(size_t i, size_t j, double value) { this->at(i)->atiminusNumber(j, value); } template inline void SparseMatrix::atijput(size_t i, size_t j, T value) { this->at(i)->atiput(j, value); } template inline double SparseMatrix::maxMagnitude() { double max = 0.0; for (size_t i = 0; i < this->size(); i++) { double element = this->at(i)->maxMagnitude(); if (max < element) max = element; } return max; } template inline std::ostream& SparseMatrix::printOn(std::ostream& s) const { s << "SpMat[" << std::endl; for (size_t i = 0; i < this->size(); i++) { s << *(this->at(i)) << std::endl; } s << "]" << std::endl; return s; } template inline FColsptr SparseMatrix::timesFullColumn(FColsptr fullCol) { //"a*b = a(i,j)b(j) sum j." auto nrow = this->nrow(); auto answer = std::make_shared>(nrow); for (size_t i = 0; i < nrow; i++) { answer->at(i) = this->at(i)->timesFullColumn(fullCol); } return answer; } template inline SpMatsptr SparseMatrix::plusSparseMatrix(SpMatsptr spMat) { //"a + b." //"Assume all checking of validity of this operation has been done." //"Just evaluate quickly." auto answer = clonesptr(); for (size_t i = 0; i < answer->size(); i++) { answer->atiput(i, answer->at(i)->plusSparseRow(spMat->at(i))); } return answer; } template inline std::shared_ptr> SparseMatrix::clonesptr() { return std::make_shared>(*this); } template inline void SparseMatrix::magnifySelf(T factor) { for (size_t i = 0; i < this->size(); i++) { this->at(i)->magnifySelf(factor); } } }