/*************************************************************************** * Copyright (c) 2023 Ondsel, Inc. * * * * This file is part of OndselSolver. * * * * See LICENSE file for details about copyright. * ***************************************************************************/ #pragma once #include "Array.h" #include "FullColumn.h" #include "FullMatrix.h" namespace MbD { template class DiagonalMatrix; template using DiagMatsptr = std::shared_ptr>; using DiagMatDsptr = std::shared_ptr>; template class DiagonalMatrix : public Array { // public: DiagonalMatrix() : Array() {} DiagonalMatrix(size_t count) : Array(count) {} DiagonalMatrix(size_t count, const T& value) : Array(count, value) {} DiagonalMatrix(std::initializer_list list) : Array{ list } {} void atiputDiagonalMatrix(size_t i, std::shared_ptr> diagMat); DiagMatsptr times(T factor); FColsptr timesFullColumn(FColsptr fullCol); FMatsptr timesFullMatrix(FMatsptr fullMat); size_t nrow() { return this->size(); } size_t ncol() { return this->size(); } double sumOfSquares() override; size_t numberOfElements() override; void zeroSelf() override; double maxMagnitude() override; std::ostream& printOn(std::ostream& s) const override; }; template<> inline DiagMatDsptr DiagonalMatrix::times(double factor) { auto nrow = this->size(); auto answer = std::make_shared>(nrow); for (size_t i = 0; i < nrow; i++) { answer->at(i) = this->at(i) * factor; } return answer; } template inline void DiagonalMatrix::atiputDiagonalMatrix(size_t i, std::shared_ptr> diagMat) { for (size_t ii = 0; ii < diagMat->size(); ii++) { this->at(i + ii) = diagMat->at(ii); } } template inline DiagMatsptr DiagonalMatrix::times(T) { throw SimulationStoppingError("To be implemented."); } template inline FColsptr DiagonalMatrix::timesFullColumn(FColsptr fullCol) { //"a*b = a(i,j)b(j) sum j." auto nrow = this->size(); auto answer = std::make_shared>(nrow); for (size_t i = 0; i < nrow; i++) { answer->at(i) = this->at(i) * fullCol->at(i); } return answer; } template inline FMatsptr DiagonalMatrix::timesFullMatrix(FMatsptr fullMat) { auto nrow = this->size(); auto answer = std::make_shared>(nrow); for (size_t i = 0; i < nrow; i++) { answer->at(i) = fullMat->at(i)->times(this->at(i)); } return answer; } template<> inline double DiagonalMatrix::sumOfSquares() { double sum = 0.0; for (size_t i = 0; i < this->size(); i++) { double element = this->at(i); sum += element * element; } return sum; } template inline size_t DiagonalMatrix::numberOfElements() { auto n = this->size(); return n * n; } template<> inline void DiagonalMatrix::zeroSelf() { for (size_t i = 0; i < this->size(); i++) { this->at(i) = 0.0; } } template<> inline double DiagonalMatrix::maxMagnitude() { double max = 0.0; for (size_t i = 0; i < this->size(); i++) { double element = this->at(i); if (element < 0.0) element = -element; if (max < element) max = element; } return max; } template inline double DiagonalMatrix::maxMagnitude() { throw SimulationStoppingError("To be implemented."); return 0.0; } template inline std::ostream& DiagonalMatrix::printOn(std::ostream& s) const { s << "DiagMat["; s << this->at(0); for (size_t i = 1; i < this->size(); i++) { s << ", " << this->at(i); } s << "]"; return s; } }