/*************************************************************************** * Copyright (c) 2023 Ondsel, Inc. * * * * This file is part of OndselSolver. * * * * See LICENSE file for details about copyright. * ***************************************************************************/ #pragma once #include #include #include #include #include //#include "Symbolic.h" namespace MbD { using ListD = std::initializer_list; using ListListD = std::initializer_list>; using ListListPairD = std::initializer_list>>; template class Array : public std::vector { public: Array() {} Array(std::vector vec) : std::vector(vec) {} Array(int count) : std::vector(count) {} Array(int count, const T& value) : std::vector(count, value) {} Array(typename std::vector::iterator begin, typename std::vector::iterator end) : std::vector(begin, end) {} Array(std::initializer_list list) : std::vector{ list } {} virtual void initialize(); void copyFrom(std::shared_ptr> x); virtual void zeroSelf(); virtual double sumOfSquares() = 0; double rootMeanSquare(); virtual int numberOfElements(); void swapElems(int i, int ii); virtual double maxMagnitude() = 0; double maxMagnitudeOfVector(); void equalArrayAt(std::shared_ptr> array, int i); virtual void atiput(int i, T value); void magnifySelf(T factor); void negateSelf(); void atitimes(int i, double factor); virtual std::ostream& printOn(std::ostream& s) const { std::string str = typeid(*this).name(); auto classname = str.substr(11, str.size() - 11); s << classname << std::endl; return s; } friend std::ostream& operator<<(std::ostream& s, const Array& array) { return array.printOn(s); } }; template inline void Array::initialize() { } template inline void Array::copyFrom(std::shared_ptr> x) { for (int i = 0; i < x->size(); i++) { this->at(i) = x->at(i); } } template inline void Array::zeroSelf() { for (int i = 0; i < this->size(); i++) { this->at(i) = (T)0; } } template inline double Array::rootMeanSquare() { return std::sqrt(this->sumOfSquares() / this->numberOfElements()); } template inline int Array::numberOfElements() { return (int)this->size(); } template inline void Array::swapElems(int i, int ii) { auto temp = this->at(i); this->at(i) = this->at(ii); this->at(ii) = temp; } //template<> //inline double Array::maxMagnitude() //{ // double 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 Array::maxMagnitudeOfVector() { double answer = 0.0; for (int i = 0; i < this->size(); i++) { double mag = std::abs(this->at(i)); if (answer < mag) answer = mag; } return answer; } template inline void Array::equalArrayAt(std::shared_ptr> array, int i) { for (int ii = 0; ii < this->size(); ii++) { this->at(ii) = array->at(i + ii); } } //template<> //inline void Array::normalizeSelf() //{ // double length = this->length(); // if (length == 0.0) throw std::runtime_error("Cannot normalize a null vector."); // this->magnifySelf(1.0 / length); //} //template<> //inline void Array::conditionSelf() //{ // constexpr double epsilon = std::numeric_limits::epsilon(); // double tol = maxMagnitude() * epsilon; // conditionSelfWithTol(tol); //} //template<> //inline void Array::conditionSelfWithTol(double tol) //{ // for (int i = 0; i < this->size(); i++) // { // double element = this->at(i); // if (element < 0.0) element = -element; // if (element < tol) this->atiput(i, 0.0); // } //} template inline void Array::atiput(int i, T value) { this->at(i) = value; } //template<> //inline double Array::length() //{ // double ssq = 0.0; // for (int i = 0; i < this->size(); i++) // { // double elem = this->at(i); // ssq += elem * elem; // } // return std::sqrt(ssq); //} template inline void Array::magnifySelf(T factor) { for (int i = 0; i < this->size(); i++) { this->atitimes(i, factor); } } template inline void Array::negateSelf() { magnifySelf(-1); } template inline void Array::atitimes(int i, double factor) { this->at(i) *= factor; } }