📄 trmd.h
字号:
// -*-C++-*- // LAPACK++ (V. 1.1)// (C) 1992-1996 All Rights Reserved.#include "arch.h"#ifndef _LA_TRIDIAG_MAT_DOUBLE_#define _LA_TRIDIAG_MAT_DOUBLE_#include "lafnames.h"#include LA_VECTOR_DOUBLE_H/** \brief Tridiagonal square matrix class * * Unlike general banded matrices, this tridiagonal matrix is * stored by diagonals rather than columns. A tridiagonal matrix * of order N is stored in three one-dimensional array, one of * length N containing the diagonal elements and two of length N-1 * containing the subdiagonal and superdiagonal elements with * element index 0 through N-2. * * One such matrix with the element indices looks as follows: * * \f[ A_{n\times n} = * \left(\begin{array}{cccc} * a_{00} & a_{01} & \cdots & 0 \\ * a_{10} & \ddots & & \\ * & & \ddots & a_{(n-2)(n-1)} \\ * 0 & \cdots & a_{(n-1)(n-2)} & a_{(n-1)(n-1)} * \end{array}\right) * \f] * * Multiplication of this matrix should be done by the functions * in blas1pp.h, blas2pp.h and blas3pp.h, * e.g. Blas_Mat_Mat_Mult(), except that currently there isn't any * function available for this class. Please ask on the * lapackpp-devel mailing list for support if you need any * assistance with this. * * \see \ref LaTridiagFactDouble, LaTridiagMatFactorize() */class DLLIMPORT LaTridiagMatDouble{ LaVectorDouble du2_; /* second upper diag, N-2 */ LaVectorDouble du_; /* upper diag, N-1 */ LaVectorDouble d_; /* main diag, N */ LaVectorDouble dl_; /* lower diag, N-1 */ int size_; static double outofbounds_; /* return this address, when addresing out of bounds */ static int debug_; // print debug info. static int *info_; // print matrix info only, not values // originally 0, set to 1, and then // reset to 0 after use. public: /** @name Declaration */ //@{ /** Constructs a null 0x0 matrix. */ LaTridiagMatDouble(); /** Constructs a tridiagonal matrix of size \f$N\times * N\f$. Matrix elements are NOT initialized! */ LaTridiagMatDouble(int N); /** Create a new matrix from an existing one by copying * (deep-copy). */ LaTridiagMatDouble(const LaTridiagMatDouble &); /** Create a new matrix from the given three diagonals. The * dimensions must match: diag must be of length N, * diaglower and diagupper of dimension N-1, otherwise a * failed assertion will terminate the program. */ LaTridiagMatDouble(const LaVectorDouble& diag, const LaVectorDouble& diaglower, const LaVectorDouble& diagupper); /** Destroy matrix and reclaim vector memory space if this * is the only structure using it. */ ~LaTridiagMatDouble(); //@} /** @name Information */ //@{ /** Returns the size \f$N\times N\f$ of this tridiagonal * square matrix. */ int size() const { return size_;} //@} /** @name Access functions */ //@{ /** Returns the \f$(i,j)\f$th element of this matrix, with the * indices i and j starting at zero (zero-based offset). This * means you have * * \f[ A_{n\times n} = * \left(\begin{array}{cccc} * a_{11} & a_{12} & \cdots & 0 \\ * a_{21} & \ddots & & \\ * & & \ddots & a_{(n-1)n} \\ * 0 & \cdots & a_{n(n-1)} & a_{nn} * \end{array}\right) * \f] * * but for accessing the element \f$a_{11}\f$ you have to * write @c A(0,0). * * Optional runtime bounds checking (0<=i<m, 0<=j<n) is set * by the compile time macro LA_BOUNDS_CHECK. * * @note This operator was broken all the way until * lapackpp-2.4.11 (regarding the lower diagonal) and is * fixed since lapackpp-2.4.12. */ inline double &operator()(int i, int j); /** Returns the \f$(i,j)\f$th element of this matrix, with the * indices i and j starting at zero (zero-based offset). This * means you have * * \f[ A_{n\times n} = * \left(\begin{array}{cccc} * a_{11} & a_{12} & \cdots & 0 \\ * a_{21} & \ddots & & \\ * & & \ddots & a_{(n-1)n} \\ * 0 & \cdots & a_{n(n-1)} & a_{nn} * \end{array}\right) * \f] * * but for accessing the element \f$a_{11}\f$ you have to * write @c A(0,0). * * Optional runtime bounds checking (0<=i<m, 0<=j<n) is set * by the compile time macro LA_BOUNDS_CHECK. * * @note This operator was broken all the way until * lapackpp-2.4.11 (regarding the lower diagonal) and is * fixed since lapackpp-2.4.12. */ inline double operator()(int i, int j) const; /** Returns the diagonal diag_selection: 0 main, -1 lower, 1 * upper, 2 second upper. * * (Actually, this class additionally stores the second * upper diagonal of length N-2, selected by * diag_selection==2, but this is only being used in * LaTridiagMatFactorize().) * * @note When assigning values or vectors to the returned * diagonals, make sure you only use LaVectorDouble::inject * instead of LaVectorDouble::copy or * LaVectorDouble::operator=(). Please write this as * follows: \verbatim LaVectorDouble newdiag(N); newdiag(0) = ...; LaTriagMatDouble triagmat(N); triagmat.diag(0).inject(newdiag); // correct // but don't write this: triagmat.diag(0) = newdiag; // wrong!\endverbatim * * Watch out: You can directly manipulate the internal * storage with this method! In particular, it would be * possible to change the length of the returned vector -- * don't do this or otherwise the tridiagonal matrix will * not be correct anymore. */ LaVectorDouble& diag(int diag_selection); /** Returns the diagonal diag_selection: 0 main, -1 lower, 1 * upper, 2 second upper. * * (Actually, this class additionally stores the second * upper diagonal of length N-2, selected by * diag_selection==2, but this is only being used in * LaTridiagMatFactorize().) * * @note When assigning values or vectors to the returned * diagonals, make sure you only use LaVectorDouble::inject * instead of LaVectorDouble::copy or * LaVectorDouble::operator=(). Please write this as * follows: \verbatim LaVectorDouble newdiag(N); newdiag(0) = ...; LaTriagMatDouble triagmat(N); triagmat.diag(0).inject(newdiag); // correct // but don't write this: triagmat.diag(0) = newdiag; // wrong!\endverbatim */ const LaVectorDouble& diag(int diag_selection) const; //@} /** @name Assignments */ //@{ /** Release left-hand side (reclaiming memory space if * possible) and copy elements of elements of \c s. Unline \c * inject(), it does not require conformity, and previous * references of left-hand side are unaffected. */ LaTridiagMatDouble& copy(const LaTridiagMatDouble& s); /** Copy elements of s into the memory space referenced by the * left-hand side, without first releasing it. The effect is * that if other matrices share memory with left-hand side, * they too will be affected. Note that the size of s must be * the same as that of the left-hand side matrix. * * @note If you rather wanted to create a new copy of \c s, * you should use \c copy() instead. */ LaTridiagMatDouble& inject(const LaTridiagMatDouble& s); /** Let this matrix reference the given matrix s, so that the * given matrix memory s is now referenced by multiple objects * (by the given object s and now also by this object). Handle * this with care! * * This function releases any previously referenced memory of * this object. */ inline LaTridiagMatDouble& ref(LaTridiagMatDouble&); //@} /** @name Debugging information */ //@{ /** // use as in // // std::cout << B.info() << std::endl; // // this *info_ member is unique in that it really isn't // part of the matrix info, just a flag as to how // to print it. We've included in this beta release // as part of our testing, but we do not expect it // to be user accessable. */ const LaTridiagMatDouble& info() const { int *t = info_; *t = 1; return *this;} /** Returns global debug flag */ int debug() const { return debug_;} //@} /** Print the matrix to the given output stream. If the matrix * info flag is set, then this prints only the matrix info, * see LaGenMatDouble::info(). Otherwise all matrix elements * are printed. * * The printing format of this NxN tridiagonal matrix is as * follows: First the N-1 elements of the superdiagonal are * printed, then the N elements of the diagonal, then the * N-1 elements of the subdiagonal. */ friend DLLIMPORT std::ostream& operator<<(std::ostream&,const LaTridiagMatDouble&);};DLLIMPORT std::ostream& operator<<(std::ostream& s, const LaTridiagMatDouble& td); // operators and member functionsinline double& LaTridiagMatDouble::operator()(int i,int j){ switch (i-j) { case 0: // main#ifdef LA_BOUNDS_CHECK if (i>d_.size()-1) return outofbounds_; else#endif return d_(i); case 1: // lower#ifdef LA_BOUNDS_CHECK if (i>dl_.size()-1) return outofbounds_; else#endif // Before lapackpp-2.4.12 this was dl_(i) but that was WRONG! return dl_(j); case -1: // upper#ifdef LA_BOUNDS_CHECK if (i>du_.size()-1) return outofbounds_; else#endif return du_(i); default: return outofbounds_; }}inline double LaTridiagMatDouble::operator()(int i,int j) const{ switch (i-j) { case 0: // main#ifdef LA_BOUNDS_CHECK if (i>d_.size()-1) return outofbounds_; else#endif return d_(i); case 1: // lower#ifdef LA_BOUNDS_CHECK if (i>dl_.size()-1) return outofbounds_; else#endif // Before lapackpp-2.4.12 this was dl_(i) but that was WRONG! return dl_(j); case -1: // upper#ifdef LA_BOUNDS_CHECK if (i>du_.size()-1) return outofbounds_; else#endif return du_(i); default: return outofbounds_; }}inline LaTridiagMatDouble& LaTridiagMatDouble::ref(LaTridiagMatDouble&T) { du2_.ref(T.du2_); du_.ref(T.du_); d_.ref(T.d_); dl_.ref(T.dl_); size_ = T.size_; return *this;}#endif // _LA_TRIDIAG_MAT_DOUBLE_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -