/*************************************************************************** * Copyright (c) 2023 Ondsel, Inc. * * * * This file is part of OndselSolver. * * * * See LICENSE file for details about copyright. * ***************************************************************************/ #pragma once #include #include #include "Array.h" namespace MbD { template class FullVector : public Array { public: FullVector() : Array() {} FullVector(std::vector vec) : Array(vec) {} FullVector(int count) : Array(count) {} FullVector(int count, const T& value) : Array(count, value) {} FullVector(typename std::vector::iterator begin, typename std::vector::iterator end) : Array(begin, end) {} FullVector(std::initializer_list list) : Array{ list } {} double dot(std::shared_ptr> vec); void atiplusNumber(int i, T value); void atiminusNumber(int i, T value); double sumOfSquares() override; int numberOfElements() override; void zeroSelf() override; void atiplusFullVector(int i, std::shared_ptr> fullVec); void atiplusFullVectortimes(int i, std::shared_ptr> fullVec, T factor); void equalSelfPlusFullVectortimes(std::shared_ptr> fullVec, T factor); double maxMagnitude() override; void normalizeSelf(); double length(); virtual void conditionSelf(); virtual void conditionSelfWithTol(double tol); std::ostream& printOn(std::ostream& s) const override; }; template inline double FullVector::dot(std::shared_ptr> vec) { int n = (int)this->size(); double answer = 0.0; for (int i = 0; i < n; i++) { answer += this->at(i) * vec->at(i); } return answer; } template inline void FullVector::atiplusNumber(int i, T value) { this->at(i) += value; } template inline void FullVector::atiminusNumber(int i, T value) { this->at(i) -= value; } template<> inline double FullVector::sumOfSquares() { double sum = 0.0; for (int i = 0; i < this->size(); i++) { double element = this->at(i); sum += element * element; } return sum; } template inline double FullVector::sumOfSquares() { assert(false); return 0.0; } template inline int FullVector::numberOfElements() { return (int)this->size(); } template<> inline void FullVector::zeroSelf() { for (int i = 0; i < this->size(); i++) { this->at(i) = 0.0; } } template inline void FullVector::zeroSelf() { assert(false); } template inline void FullVector::atiplusFullVector(int i1, std::shared_ptr> fullVec) { for (int ii = 0; ii < fullVec->size(); ii++) { auto i = i1 + ii; this->at(i) += fullVec->at(ii); } } template inline void FullVector::atiplusFullVectortimes(int i1, std::shared_ptr> fullVec, T factor) { for (int ii = 0; ii < fullVec->size(); ii++) { auto i = i1 + ii; this->at(i) += fullVec->at(ii) * factor; } } template inline void FullVector::equalSelfPlusFullVectortimes(std::shared_ptr> fullVec, T factor) { for (int i = 0; i < this->size(); i++) { this->atiplusNumber(i, fullVec->at(i) * factor); } } template<> inline double FullVector::maxMagnitude() { auto max = 0.0; for (int i = 0; i < this->size(); i++) { auto element = this->at(i); if (element < 0.0) element = -element; if (max < element) max = element; } return max; } template inline double FullVector::maxMagnitude() { assert(false); return 0.0; } template<> inline void FullVector::normalizeSelf() { auto length = this->length(); if (length == 0.0) throw std::runtime_error("Cannot normalize a null vector."); this->magnifySelf(1.0 / length); } template inline double FullVector::length() { auto ssq = 0.0; for (int i = 0; i < this->size(); i++) { auto elem = this->at(i); ssq += elem * elem; } return std::sqrt(ssq); } template inline void FullVector::conditionSelf() { constexpr auto epsilon = std::numeric_limits::epsilon(); auto tol = this->maxMagnitude() * epsilon; this->conditionSelfWithTol(tol); } template<> inline void FullVector::conditionSelfWithTol(double tol) { for (int i = 0; i < this->size(); i++) { auto element = this->at(i); if (element < 0.0) element = -element; if (element < tol) this->atiput(i, 0.0); } } template inline void FullVector::conditionSelfWithTol(double tol) { assert(false); return; } template inline std::ostream& FullVector::printOn(std::ostream& s) const { s << "FullVec{"; s << this->at(0); for (int i = 1; i < this->size(); i++) { s << ", " << this->at(i); } s << "}"; return s; } }