TridiagonalMatrix.hpp
Go to the documentation of this file.
1 // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 // vi: set et ts=4 sw=4 sts=4:
3 /*
4  Copyright (C) 2010-2013 by Andreas Lauser
5 
6  This file is part of the Open Porous Media project (OPM).
7 
8  OPM is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 2 of the License, or
11  (at your option) any later version.
12 
13  OPM is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with OPM. If not, see <http://www.gnu.org/licenses/>.
20 */
25 #ifndef OPM_TRIDIAGONAL_MATRIX_HH
26 #define OPM_TRIDIAGONAL_MATRIX_HH
27 
28 #include <iostream>
29 #include <vector>
30 #include <algorithm>
31 #include <cmath>
32 
33 #include <assert.h>
34 
35 namespace Opm {
36 
47 template <class Scalar>
49 {
50  struct TridiagRow_ {
51  TridiagRow_(TridiagonalMatrix &m, size_t rowIdx)
52  : matrix_(m)
53  , rowIdx_(rowIdx)
54  {}
55 
56  Scalar &operator[](size_t colIdx)
57  { return matrix_.at(rowIdx_, colIdx); }
58 
59  Scalar operator[](size_t colIdx) const
60  { return matrix_.at(rowIdx_, colIdx); }
61 
65  TridiagRow_ &operator++()
66  { ++ rowIdx_; return *this; }
67 
71  TridiagRow_ &operator--()
72  { -- rowIdx_; return *this; }
73 
77  bool operator==(const TridiagRow_ &other) const
78  { return other.rowIdx_ == rowIdx_ && &other.matrix_ == &matrix_; }
79 
83  bool operator!=(const TridiagRow_ &other) const
84  { return !operator==(other); }
85 
89  TridiagRow_ &operator*()
90  { return *this; }
91 
97  size_t index() const
98  { return rowIdx_; }
99 
100  private:
101  TridiagonalMatrix &matrix_;
102  mutable size_t rowIdx_;
103  };
104 
105 public:
106  typedef Scalar FieldType;
107  typedef TridiagRow_ RowType;
108  typedef size_t SizeType;
109  typedef TridiagRow_ iterator;
110  typedef TridiagRow_ const_iterator;
111 
112  explicit TridiagonalMatrix(size_t numRows = 0)
113  {
114  resize(numRows);
115  }
116 
117  TridiagonalMatrix(size_t numRows, Scalar value)
118  {
119  resize(numRows);
120  this->operator=(value);
121  }
122 
127  { *this = source; }
128 
132  size_t size() const
133  { return diag_[0].size(); }
134 
138  size_t rows() const
139  { return size(); }
140 
144  size_t cols() const
145  { return size(); }
146 
150  void resize(size_t n)
151  {
152  if (n == size())
153  return;
154 
155  for (int diagIdx = 0; diagIdx < 3; ++ diagIdx)
156  diag_[diagIdx].resize(n);
157  }
158 
162  Scalar &at(size_t rowIdx, size_t colIdx)
163  {
164  size_t n = size();
165 
166  // special cases
167  if (n > 2) {
168  if (rowIdx == 0 && colIdx == n - 1)
169  return diag_[2][0];
170  if (rowIdx == n - 1 && colIdx == 0)
171  return diag_[0][n - 1];
172  }
173 
174  size_t diagIdx = 1 + colIdx - rowIdx;
175  // make sure that the requested column is in range
176  assert(0 <= diagIdx && diagIdx < 3);
177  return diag_[diagIdx][colIdx];
178  }
179 
183  Scalar at(size_t rowIdx, size_t colIdx) const
184  {
185  int n = size();
186 
187  // special cases
188  if (rowIdx == 0 && colIdx == n - 1)
189  return diag_[2][0];
190  if (rowIdx == n - 1 && colIdx == 0)
191  return diag_[0][n - 1];
192 
193  int diagIdx = 1 + colIdx - rowIdx;
194  // make sure that the requested column is in range
195  assert(0 <= diagIdx && diagIdx < 3);
196  return diag_[diagIdx][colIdx];
197  }
198 
203  {
204  for (int diagIdx = 0; diagIdx < 3; ++ diagIdx)
205  diag_[diagIdx] = source.diag_[diagIdx];
206 
207  return *this;
208  }
209 
214  {
215  for (int diagIdx = 0; diagIdx < 3; ++ diagIdx)
216  diag_[diagIdx].assign(size(), value);
217 
218  return *this;
219  }
220 
224  iterator begin()
225  { return TridiagRow_(*this, 0); }
226 
230  const_iterator begin() const
231  { return TridiagRow_(const_cast<TridiagonalMatrix&>(*this), 0); }
232 
236  const_iterator end() const
237  { return TridiagRow_(const_cast<TridiagonalMatrix&>(*this), size()); }
238 
242  TridiagRow_ operator[](size_t rowIdx)
243  { return TridiagRow_(*this, rowIdx); }
244 
248  const TridiagRow_ operator[](size_t rowIdx) const
249  { return TridiagRow_(*this, rowIdx); }
250 
255  {
256  int n = size();
257  for (int diagIdx = 0; diagIdx < 3; ++ diagIdx) {
258  for (int i = 0; i < n; ++i) {
259  diag_[diagIdx][i] *= alpha;
260  }
261  }
262 
263  return *this;
264  }
265 
270  {
271  alpha = 1.0/alpha;
272  int n = size();
273  for (int diagIdx = 0; diagIdx < 3; ++ diagIdx) {
274  for (int i = 0; i < n; ++i) {
275  diag_[diagIdx][i] *= alpha;
276  }
277  }
278 
279  return *this;
280  }
281 
286  { return axpy(-1.0, other); }
287 
292  { return axpy(1.0, other); }
293 
294 
308  TridiagonalMatrix &axpy(Scalar alpha, const TridiagonalMatrix &other)
309  {
310  assert(size() == other.size());
311 
312  int n = size();
313  for (int diagIdx = 0; diagIdx < 3; ++ diagIdx)
314  for (int i = 0; i < n; ++ i)
315  diag_[diagIdx][i] += alpha * other[diagIdx][i];
316 
317  return *this;
318  }
319 
332  template<class Vector>
333  void mv(const Vector &source, Vector &dest) const
334  {
335  assert(source.size() == size());
336  assert(dest.size() == size());
337  assert(size() > 1);
338 
339  // deal with rows 1 .. n-2
340  int n = size();
341  for (int i = 1; i < n - 1; ++ i) {
342  dest[i] =
343  diag_[0][i - 1]*source[i-1] +
344  diag_[1][i]*source[i] +
345  diag_[2][i + 1]*source[i + 1];
346  }
347 
348  // rows 0 and n-1
349  dest[0] =
350  diag_[1][0]*source[0] +
351  diag_[2][1]*source[1] +
352  diag_[2][0]*source[n - 1];
353 
354  dest[n - 1] =
355  diag_[0][n-1]*source[0] +
356  diag_[0][n-2]*source[n-2] +
357  diag_[1][n-1]*source[n-1];
358  }
359 
372  template<class Vector>
373  void umv(const Vector &source, Vector &dest) const
374  {
375  assert(source.size() == size());
376  assert(dest.size() == size());
377  assert(size() > 1);
378 
379  // deal with rows 1 .. n-2
380  int n = size();
381  for (int i = 1; i < n - 1; ++ i) {
382  dest[i] +=
383  diag_[0][i - 1]*source[i-1] +
384  diag_[1][i]*source[i] +
385  diag_[2][i + 1]*source[i + 1];
386  }
387 
388  // rows 0 and n-1
389  dest[0] +=
390  diag_[1][0]*source[0] +
391  diag_[2][1]*source[1] +
392  diag_[2][0]*source[n - 1];
393 
394  dest[n - 1] +=
395  diag_[0][n-1]*source[0] +
396  diag_[0][n-2]*source[n-2] +
397  diag_[1][n-1]*source[n-1];
398  }
399 
412  template<class Vector>
413  void mmv(const Vector &source, Vector &dest) const
414  {
415  assert(source.size() == size());
416  assert(dest.size() == size());
417  assert(size() > 1);
418 
419  // deal with rows 1 .. n-2
420  int n = size();
421  for (int i = 1; i < n - 1; ++ i) {
422  dest[i] -=
423  diag_[0][i - 1]*source[i-1] +
424  diag_[1][i]*source[i] +
425  diag_[2][i + 1]*source[i + 1];
426  }
427 
428  // rows 0 and n-1
429  dest[0] -=
430  diag_[1][0]*source[0] +
431  diag_[2][1]*source[1] +
432  diag_[2][0]*source[n - 1];
433 
434  dest[n - 1] -=
435  diag_[0][n-1]*source[0] +
436  diag_[0][n-2]*source[n-2] +
437  diag_[1][n-1]*source[n-1];
438  }
439 
452  template<class Vector>
453  void usmv(Scalar alpha, const Vector &source, Vector &dest) const
454  {
455  assert(source.size() == size());
456  assert(dest.size() == size());
457  assert(size() > 1);
458 
459  // deal with rows 1 .. n-2
460  int n = size();
461  for (int i = 1; i < n - 1; ++ i) {
462  dest[i] +=
463  alpha*(
464  diag_[0][i - 1]*source[i-1] +
465  diag_[1][i]*source[i] +
466  diag_[2][i + 1]*source[i + 1]);
467  }
468 
469  // rows 0 and n-1
470  dest[0] +=
471  alpha*(
472  diag_[1][0]*source[0] +
473  diag_[2][1]*source[1] +
474  diag_[2][0]*source[n - 1]);
475 
476  dest[n - 1] +=
477  alpha*(
478  diag_[0][n-1]*source[0] +
479  diag_[0][n-2]*source[n-2] +
480  diag_[1][n-1]*source[n-1]);
481  }
482 
495  template<class Vector>
496  void mtv(const Vector &source, Vector &dest) const
497  {
498  assert(source.size() == size());
499  assert(dest.size() == size());
500  assert(size() > 1);
501 
502  // deal with rows 1 .. n-2
503  int n = size();
504  for (int i = 1; i < n - 1; ++ i) {
505  dest[i] =
506  diag_[2][i + 1]*source[i-1] +
507  diag_[1][i]*source[i] +
508  diag_[0][i - 1]*source[i + 1];
509  }
510 
511  // rows 0 and n-1
512  dest[0] =
513  diag_[1][0]*source[0] +
514  diag_[0][1]*source[1] +
515  diag_[0][n-1]*source[n - 1];
516 
517  dest[n - 1] =
518  diag_[2][0]*source[0] +
519  diag_[2][n-1]*source[n-2] +
520  diag_[1][n-1]*source[n-1];
521  }
522 
535  template<class Vector>
536  void umtv(const Vector &source, Vector &dest) const
537  {
538  assert(source.size() == size());
539  assert(dest.size() == size());
540  assert(size() > 1);
541 
542  // deal with rows 1 .. n-2
543  int n = size();
544  for (int i = 1; i < n - 1; ++ i) {
545  dest[i] +=
546  diag_[2][i + 1]*source[i-1] +
547  diag_[1][i]*source[i] +
548  diag_[0][i - 1]*source[i + 1];
549  }
550 
551  // rows 0 and n-1
552  dest[0] +=
553  diag_[1][0]*source[0] +
554  diag_[0][1]*source[1] +
555  diag_[0][n-1]*source[n - 1];
556 
557  dest[n - 1] +=
558  diag_[2][0]*source[0] +
559  diag_[2][n-1]*source[n-2] +
560  diag_[1][n-1]*source[n-1];
561  }
562 
575  template<class Vector>
576  void mmtv (const Vector &source, Vector &dest) const
577  {
578  assert(source.size() == size());
579  assert(dest.size() == size());
580  assert(size() > 1);
581 
582  // deal with rows 1 .. n-2
583  int n = size();
584  for (int i = 1; i < n - 1; ++ i) {
585  dest[i] -=
586  diag_[2][i + 1]*source[i-1] +
587  diag_[1][i]*source[i] +
588  diag_[0][i - 1]*source[i + 1];
589  }
590 
591  // rows 0 and n-1
592  dest[0] -=
593  diag_[1][0]*source[0] +
594  diag_[0][1]*source[1] +
595  diag_[0][n-1]*source[n - 1];
596 
597  dest[n - 1] -=
598  diag_[2][0]*source[0] +
599  diag_[2][n-1]*source[n-2] +
600  diag_[1][n-1]*source[n-1];
601  }
602 
615  template<class Vector>
616  void usmtv(Scalar alpha, const Vector &source, Vector &dest) const
617  {
618  assert(source.size() == size());
619  assert(dest.size() == size());
620  assert(size() > 1);
621 
622  // deal with rows 1 .. n-2
623  int n = size();
624  for (int i = 1; i < n - 1; ++ i) {
625  dest[i] +=
626  alpha*(
627  diag_[2][i + 1]*source[i-1] +
628  diag_[1][i]*source[i] +
629  diag_[0][i - 1]*source[i + 1]);
630  }
631 
632  // rows 0 and n-1
633  dest[0] +=
634  alpha*(
635  diag_[1][0]*source[0] +
636  diag_[0][1]*source[1] +
637  diag_[0][n-1]*source[n - 1]);
638 
639  dest[n - 1] +=
640  alpha*(
641  diag_[2][0]*source[0] +
642  diag_[2][n-1]*source[n-2] +
643  diag_[1][n-1]*source[n-1]);
644  }
645 
652  Scalar frobeniusNorm() const
653  { return std::sqrt(frobeniusNormSquared()); }
654 
660  Scalar frobeniusNormSquared() const
661  {
662  Scalar result = 0;
663 
664  int n = size();
665  for (int i = 0; i < n; ++ i)
666  for (int diagIdx = 0; diagIdx < 3; ++ diagIdx)
667  result += diag_[diagIdx][i];
668 
669  return result;
670  }
671 
677  Scalar infinityNorm() const
678  {
679  Scalar result=0;
680 
681  // deal with rows 1 .. n-2
682  int n = size();
683  for (int i = 1; i < n - 1; ++ i) {
684  result = std::max(result,
685  std::abs(diag_[0][i - 1]) +
686  std::abs(diag_[1][i]) +
687  std::abs(diag_[2][i + 1]));
688  }
689 
690  // rows 0 and n-1
691  result = std::max(result,
692  std::abs(diag_[1][0]) +
693  std::abs(diag_[2][1]) +
694  std::abs(diag_[2][0]));
695 
696 
697  result = std::max(result,
698  std::abs(diag_[0][n-1]) +
699  std::abs(diag_[0][n-2]) +
700  std::abs(diag_[1][n-2]));
701 
702  return result;
703  }
704 
711  template <class XVector, class BVector>
712  void solve(XVector &x, const BVector &b) const
713  {
714  if (size() > 2 && std::abs(diag_[2][0]) < 1e-30)
715  solveWithUpperRight_(x, b);
716  else
717  solveWithoutUpperRight_(x, b);
718  }
719 
723  void print(std::ostream &os = std::cout) const
724  {
725  int n = size();
726 
727  // row 0
728  os << at(0, 0) << "\t"
729  << at(0, 1) << "\t";
730 
731  if (n > 3)
732  os << "\t";
733  if (n > 2)
734  os << at(0, n-1);
735  os << "\n";
736 
737  // row 1 .. n - 2
738  for (int rowIdx = 1; rowIdx < n-1; ++rowIdx) {
739  if (rowIdx > 1)
740  os << "\t";
741  if (rowIdx == n - 2)
742  os << "\t";
743 
744  os << at(rowIdx, rowIdx - 1) << "\t"
745  << at(rowIdx, rowIdx) << "\t"
746  << at(rowIdx, rowIdx + 1) << "\n";
747  }
748 
749  // row n - 1
750  if (n > 2)
751  os << at(n-1, 0) << "\t";
752  if (n > 3)
753  os << "\t";
754  if (n > 4)
755  os << "\t";
756  os << at(n-1, n-2) << "\t"
757  << at(n-1, n-1) << "\n";
758  }
759 
760 private:
761  template <class XVector, class BVector>
762  void solveWithUpperRight_(XVector &x, const BVector &b) const
763  {
764  size_t n = size();
765 
766  std::vector<Scalar> lowerDiag(diag_[0]), mainDiag(diag_[1]), upperDiag(diag_[2]), lastColumn(n);
767  std::vector<Scalar> bStar(n);
768  std::copy(b.begin(), b.end(), bStar.begin());
769 
770  lastColumn[0] = upperDiag[0];
771 
772  // forward elimination
773  for (size_t i = 1; i < n; ++i) {
774  Scalar alpha = lowerDiag[i - 1]/mainDiag[i - 1];
775 
776  lowerDiag[i - 1] -= alpha * mainDiag[i - 1];
777  mainDiag[i] -= alpha * upperDiag[i];
778 
779  bStar[i] -= alpha * bStar[i - 1];
780  };
781 
782  // deal with the last row if the entry on the lower left is not zero
783  if (lowerDiag[n - 1] != 0.0 && size() > 2) {
784  Scalar lastRow = lowerDiag[n - 1];
785  for (size_t i = 0; i < n - 1; ++i) {
786  Scalar alpha = lastRow/mainDiag[i];
787  lastRow = - alpha*upperDiag[i + 1];
788  bStar[n - 1] -= alpha * bStar[i];
789  }
790 
791  mainDiag[n-1] += lastRow;
792  }
793 
794  // backward elimination
795  x[n - 1] = bStar[n - 1]/mainDiag[n-1];
796  for (int i = static_cast<int>(n) - 2; i >= 0; --i) {
797  unsigned iu = static_cast<unsigned>(i);
798  x[iu] = (bStar[iu] - x[iu + 1]*upperDiag[iu+1] - x[n-1]*lastColumn[iu])/mainDiag[iu];
799  }
800  }
801 
802  template <class XVector, class BVector>
803  void solveWithoutUpperRight_(XVector &x, const BVector &b) const
804  {
805  size_t n = size();
806 
807  std::vector<Scalar> lowerDiag(diag_[0]), mainDiag(diag_[1]), upperDiag(diag_[2]);
808  std::vector<Scalar> bStar(n);
809  std::copy(b.begin(), b.end(), bStar.begin());
810 
811  // forward elimination
812  for (size_t i = 1; i < n; ++i) {
813  Scalar alpha = lowerDiag[i - 1]/mainDiag[i - 1];
814 
815  lowerDiag[i - 1] -= alpha * mainDiag[i - 1];
816  mainDiag[i] -= alpha * upperDiag[i];
817 
818  bStar[i] -= alpha * bStar[i - 1];
819  };
820 
821  // deal with the last row if the entry on the lower left is not zero
822  if (lowerDiag[n - 1] != 0.0 && size() > 2) {
823  Scalar lastRow = lowerDiag[n - 1];
824  for (size_t i = 0; i < n - 1; ++i) {
825  Scalar alpha = lastRow/mainDiag[i];
826  lastRow = - alpha*upperDiag[i + 1];
827  bStar[n - 1] -= alpha * bStar[i];
828  }
829 
830  mainDiag[n-1] += lastRow;
831  }
832 
833  // backward elimination
834  x[n - 1] = bStar[n - 1]/mainDiag[n-1];
835  for (int i = static_cast<int>(n) - 2; i >= 0; --i) {
836  unsigned iu = static_cast<unsigned>(i);
837  x[iu] = (bStar[iu] - x[iu + 1]*upperDiag[iu+1])/mainDiag[iu];
838  }
839  }
840 
841  mutable std::vector<Scalar> diag_[3];
842 };
843 
844 } // namespace Opm
845 
846 template <class Scalar>
847 std::ostream &operator<<(std::ostream &os, const Opm::TridiagonalMatrix<Scalar> &mat)
848 {
849  mat.print(os);
850  return os;
851 }
852 
853 #endif
void solve(XVector &x, const BVector &b) const
Calculate the solution for a linear system of equations.
Definition: TridiagonalMatrix.hpp:712
Scalar FieldType
Definition: TridiagonalMatrix.hpp:106
Provides a tridiagonal matrix that also supports non-zero entries in the upper right and lower left...
Definition: TridiagonalMatrix.hpp:48
TridiagonalMatrix(size_t numRows=0)
Definition: TridiagonalMatrix.hpp:112
Evaluation< Scalar, VarSetTag, numVars > operator*(const ScalarA &a, const Evaluation< Scalar, VarSetTag, numVars > &b)
Definition: Evaluation.hpp:403
const TridiagRow_ operator[](size_t rowIdx) const
Row access operator.
Definition: TridiagonalMatrix.hpp:248
Definition: Air_Mesitylene.hpp:31
TridiagonalMatrix & operator*=(Scalar alpha)
Multiplication with a Scalar.
Definition: TridiagonalMatrix.hpp:254
TridiagonalMatrix(const TridiagonalMatrix &source)
Copy constructor.
Definition: TridiagonalMatrix.hpp:126
Scalar frobeniusNormSquared() const
Calculate the squared frobenius norm.
Definition: TridiagonalMatrix.hpp:660
void umtv(const Vector &source, Vector &dest) const
Transposed additive matrix-vector product.
Definition: TridiagonalMatrix.hpp:536
void mv(const Vector &source, Vector &dest) const
Matrix-vector product.
Definition: TridiagonalMatrix.hpp:333
void mtv(const Vector &source, Vector &dest) const
Transposed matrix-vector product.
Definition: TridiagonalMatrix.hpp:496
Evaluation< Scalar, VarSetTag, numVars > max(const Evaluation< Scalar, VarSetTag, numVars > &x1, const Evaluation< Scalar, VarSetTag, numVars > &x2)
Definition: Math.hpp:114
Scalar & at(size_t rowIdx, size_t colIdx)
Access an entry.
Definition: TridiagonalMatrix.hpp:162
Evaluation< Scalar, VarSetTag, numVars > sqrt(const Evaluation< Scalar, VarSetTag, numVars > &x)
Definition: Math.hpp:278
void mmv(const Vector &source, Vector &dest) const
Subtractive matrix-vector product.
Definition: TridiagonalMatrix.hpp:413
iterator begin()
Definition: TridiagonalMatrix.hpp:224
void usmtv(Scalar alpha, const Vector &source, Vector &dest) const
Transposed scaled additive matrix-vector product.
Definition: TridiagonalMatrix.hpp:616
void resize(size_t n)
Change the number of rows of the matrix.
Definition: TridiagonalMatrix.hpp:150
TridiagonalMatrix & operator=(const TridiagonalMatrix &source)
Assignment operator from another tridiagonal matrix.
Definition: TridiagonalMatrix.hpp:202
void print(std::ostream &os=std::cout) const
Print the matrix to a given output stream.
Definition: TridiagonalMatrix.hpp:723
bool operator!=(const ScalarA &a, const Evaluation< Scalar, VarSetTag, numVars > &b)
Definition: Evaluation.hpp:362
size_t cols() const
Return the number of columns of the matrix.
Definition: TridiagonalMatrix.hpp:144
Evaluation< Scalar, VarSetTag, numVars > abs(const Evaluation< Scalar, VarSetTag, numVars > &)
Definition: Math.hpp:41
TridiagonalMatrix & operator+=(const TridiagonalMatrix &other)
Addition operator.
Definition: TridiagonalMatrix.hpp:291
Scalar infinityNorm() const
Calculate the infinity norm.
Definition: TridiagonalMatrix.hpp:677
TridiagRow_ RowType
Definition: TridiagonalMatrix.hpp:107
void mmtv(const Vector &source, Vector &dest) const
Transposed subtractive matrix-vector product.
Definition: TridiagonalMatrix.hpp:576
const_iterator end() const
Definition: TridiagonalMatrix.hpp:236
TridiagonalMatrix & operator-=(const TridiagonalMatrix &other)
Subtraction operator.
Definition: TridiagonalMatrix.hpp:285
TridiagonalMatrix & operator/=(Scalar alpha)
Division by a Scalar.
Definition: TridiagonalMatrix.hpp:269
size_t size() const
Return the number of rows/columns of the matrix.
Definition: TridiagonalMatrix.hpp:132
Scalar frobeniusNorm() const
Calculate the frobenius norm.
Definition: TridiagonalMatrix.hpp:652
TridiagonalMatrix & operator=(Scalar value)
Assignment operator from a Scalar.
Definition: TridiagonalMatrix.hpp:213
void umv(const Vector &source, Vector &dest) const
Additive matrix-vector product.
Definition: TridiagonalMatrix.hpp:373
TridiagRow_ const_iterator
Definition: TridiagonalMatrix.hpp:110
TridiagonalMatrix(size_t numRows, Scalar value)
Definition: TridiagonalMatrix.hpp:117
size_t rows() const
Return the number of rows of the matrix.
Definition: TridiagonalMatrix.hpp:138
TridiagonalMatrix & axpy(Scalar alpha, const TridiagonalMatrix &other)
Multiply and add the matrix entries of another tridiagonal matrix.
Definition: TridiagonalMatrix.hpp:308
void usmv(Scalar alpha, const Vector &source, Vector &dest) const
Scaled additive matrix-vector product.
Definition: TridiagonalMatrix.hpp:453
Scalar at(size_t rowIdx, size_t colIdx) const
Access an entry.
Definition: TridiagonalMatrix.hpp:183
size_t SizeType
Definition: TridiagonalMatrix.hpp:108
TridiagRow_ operator[](size_t rowIdx)
Row access operator.
Definition: TridiagonalMatrix.hpp:242
const_iterator begin() const
Definition: TridiagonalMatrix.hpp:230
TridiagRow_ iterator
Definition: TridiagonalMatrix.hpp:109