/*************************************************************************** * 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" namespace MbD { template class SparseMatrix; using SpMatDsptr = std::shared_ptr>; template class SparseMatrix : public RowTypeMatrix> { public: SparseMatrix(int m) : RowTypeMatrix>(m) { } SparseMatrix(int m, int n) { for (int 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(int i, SpRowsptr spRow); void atijplusDiagonalMatrix(int i, int j, DiagMatDsptr diagMat); void atijminusDiagonalMatrix(int i, int j, DiagMatDsptr diagMat); double sumOfSquares() override; void zeroSelf() override; void atijplusFullRow(int i, int j, FRowsptr fullRow); void atijplusFullColumn(int i, int j, FColsptr fullCol); void atijplusFullMatrix(int i, int j, FMatsptr fullMat); void atijminusFullMatrix(int i, int j, FMatsptr fullMat); void atijplusTransposeFullMatrix(int i, int j, FMatsptr fullMat); void atijplusFullMatrixtimes(int i, int j, FMatsptr fullMat, T factor); void atijplusNumber(int i, int j, double value); void atijminusNumber(int i, int j, double value); void atijput(int i, int j, T value); double maxMagnitude() override; FColsptr timesFullColumn(FColsptr fullCol); std::ostream& printOn(std::ostream& s) const override; }; template inline void SparseMatrix::atiput(int i, SpRowsptr spRow) { this->at(i) = spRow; } template inline void SparseMatrix::atijplusDiagonalMatrix(int i, int j, DiagMatDsptr diagMat) { auto n = diagMat->nrow(); for (int ii = 0; ii < n; ii++) { this->atijplusNumber(i + ii, j + ii, diagMat->at(ii)); } } template<> inline void SparseMatrix::atijminusDiagonalMatrix(int i1, int j1, DiagMatDsptr diagMat) { auto n = diagMat->nrow(); for (int ii = 0; ii < n; ii++) { this->atijminusNumber(i1 + ii, j1 + ii, diagMat->at(ii)); } } template inline double SparseMatrix::sumOfSquares() { double sum = 0.0; for (int i = 0; i < this->size(); i++) { sum += this->at(i)->sumOfSquares(); } return sum; } template<> inline void SparseMatrix::zeroSelf() { for (int i = 0; i < this->size(); i++) { this->at(i)->zeroSelf(); } } template inline void SparseMatrix::atijplusFullRow(int i, int j, FRowsptr fullRow) { this->at(i)->atiplusFullRow(j, fullRow); } template inline void SparseMatrix::atijplusFullColumn(int i, int j, FColsptr fullCol) { for (int ii = 0; ii < fullCol->size(); ii++) { this->atijplusNumber(i + ii, j, fullCol->at(ii)); } } template inline void SparseMatrix::atijplusFullMatrix(int i, int j, FMatsptr fullMat) { for (int ii = 0; ii < fullMat->nrow(); ii++) { this->at(i + ii)->atiplusFullRow(j, fullMat->at(ii)); } } template inline void SparseMatrix::atijminusFullMatrix(int i, int j, FMatsptr fullMat) { for (int ii = 0; ii < fullMat->nrow(); ii++) { this->at(i + ii)->atiminusFullRow(j, fullMat->at(ii)); } } template inline void SparseMatrix::atijplusTransposeFullMatrix(int i, int j, FMatsptr fullMat) { for (int ii = 0; ii < fullMat->nrow(); ii++) { this->atijplusFullColumn(i, j + ii, fullMat->at(ii)->transpose()); } } template inline void SparseMatrix::atijplusFullMatrixtimes(int i, int j, FMatsptr fullMat, T factor) { for (int ii = 0; ii < fullMat->nrow(); ii++) { this->at(i + ii)->atiplusFullRowtimes(j, fullMat->at(ii), factor); } } template inline void SparseMatrix::atijplusNumber(int i, int j, double value) { this->at(i)->atiplusNumber(j, value); } template inline void SparseMatrix::atijminusNumber(int i, int j, double value) { this->at(i)->atiminusNumber(j, value); } template inline void SparseMatrix::atijput(int i, int j, T value) { this->at(i)->atiput(j, value); } template inline double SparseMatrix::maxMagnitude() { auto max = 0.0; for (int i = 0; i < this->size(); i++) { auto 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 (int 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 (int i = 0; i < nrow; i++) { answer->at(i) = this->at(i)->timesFullColumn(fullCol); } return answer; } }