#pragma once #ifndef __TRIDIAG_H__ #define __TRIDIAG_H__ template class tridiag { std::vector diag, lower, upper; struct row { std::size_t index; tridiag& ref; T shared_zero = 0; row(std::size_t i, tridiag& _ref) : index(i), ref(_ref) {} T& operator[](std::size_t j) { switch(static_cast(j) - index) { case -1: return ref.lower[j]; case 0: return ref.diag[j]; case 1: return ref.upper[index]; default: shared_zero = 0; // assure zero return shared_zero; } } }; struct const_row { std::size_t index; const tridiag& ref; const T shared_zero = 0; const_row(std::size_t i, const tridiag& _ref) : index(i), ref(_ref) {} const T& operator[](std::size_t j) const { switch(static_cast(j) - index) { case -1: return ref.lower[j]; case 0: return ref.diag[j]; case 1: return ref.upper[index]; default: return shared_zero; } } }; public: tridiag(std::size_t N = 1) : diag(N), lower(N-1), upper(N-1) { } void resize(std::size_t N) { diag.reserve(N); lower.reserve(N-1); upper.reserve(N-1); } void zeros() { for (std::size_t i = 0; i < size()-1; ++i) diag[i] = lower[i] = upper[i] = 0; diag[size()-1] = 0; } // set diagonal to zero void zeros_diag() { for (std::size_t i = 0; i < size(); ++i) diag[i] = 0; } row operator[](std::size_t i) { return row(i, *this); } const const_row operator[](std::size_t i) const { return const_row(i, *this); } std::size_t size() const { return diag.size(); } template