📄 matview.hpp
字号:
// $mat\matview.hpp 1.5 milbo$ matrix view class, see mat.hpp for a description// Warning: this is raw research code -- expect it to be quite messy.//// milbo jun05 petaluma#if !defined(matview_hpp)#define matview_hpp#include "mat.hpp"namespace GslMat{//-----------------------------------------------------------------------------// Note: a destructor is unneeded because ~Mat suffices. When ~Mat destructs// a MatView, it sees that m->owner == 0 and thus it knows that it should not// release the matrix being viewed.// Address-of operator also unneeded, compiler default is ok.class MatView : public Mat{public:MatView() {} // default constructorMatView (const Mat &other) { init(other); } // copy constructorsMatView (const MatView &other) { init(other); }// view matrix/view/array as a matrix by initializing a view with two dimensionsMatView (const Mat &other, size_t iStartRow, size_t iStartCol, size_t nrows1, size_t ncols1, int Tda=0) :Mat() { init(other, iStartRow, iStartCol, nrows1, ncols1, Tda); }MatView (double other[], size_t iStartRow, size_t iStartCol, size_t nrows1, size_t ncols1, int Tda=0) :Mat() { init(other, iStartRow, iStartCol, nrows1, ncols1, Tda); }MatView (double other[], size_t nrows1, size_t ncols1, int Tda) :Mat() //TODO tda is compulsory for now to disambiguate { //TODO not tested in test.cpp init(other, 0, 0, nrows1, ncols1, Tda); }// view matrix/view/array as vector by initializing a view with single dimension// See also row, rowAsCol, etc.MatView (const Mat &other, size_t iStart, char *sIsRowVec=NULL) :Mat() { sIsRowVec? init(other, iStart, 0, 1, other.ncols()): init(other, 0, iStart, other.nrows(), 1); }MatView (double other[], size_t iStart, size_t nelems, char *sIsRowVec=NULL) :Mat() { sIsRowVec? init(other, iStart, 0, 1, nelems, 1): init(other, 0, iStart, nelems, 1); }MatView (double other[], size_t nelems, char *sIsRowVec=NULL): Mat() //TODO not tested in test.cpp { sIsRowVec? init(other, 0, 0, 1, nelems, 1): init(other, 0, 0, nelems, 1); }// Equals operator copies all matrix elements (not just struct m)// If you just want to refer to another matrix without copying elements, use init(other)MatView& MatView::operator= (const MatView &other) { if (static_cast<const void *>(this) == static_cast<const void *>(&other)) return *this; DASSERT(other.m); // this func doesn't handle zero size other (yet) if (!m) { lprintf("!m\n"); m = (gsl_matrix *)calloc(sizeof(gsl_matrix), 1); memcpy(m, other.m, sizeof(gsl_matrix)); } gsl_matrix_memcpy(m, other.m); m->block = NULL; m->owner = 0; return *this; }// redimension (this simply changes the sizes and doesn't change the underlying data)void MatView::dim (size_t nrows1, size_t ncols1) { m->size1 = nrows1; m->size2 = ncols1; m->tda = ncols1; }void MatView::init (const Mat& other) { DASSERT(static_cast<const void *>(this) != static_cast<const void *>(&other)); if (!m) m = (gsl_matrix *)calloc(sizeof(gsl_matrix), 1); if (other.m) memcpy(m, other.m, sizeof(gsl_matrix)); m->block = NULL; m->owner = 0; }void MatView::init (const Mat& other, size_t iStartRow, size_t iStartCol, size_t nrows1, size_t ncols1, int Tda=0) { DASSERT(static_cast<const void *>(this) != static_cast<const void *>(&other)); DASSERT(other.m); // doesn't make sense to view a zero sized matrix this way #if GSL_RANGE_CHECK CheckReasonableDim(iStartRow, iStartCol, 0, "MatView bad start row %d or column %d"); CheckReasonableDim(nrows1, ncols1, 1, "MatView bad number of rows %d or columns %d"); #endif if (!m) m = (gsl_matrix *)malloc(sizeof(gsl_matrix)); m->size1 = nrows1; m->size2 = ncols1; m->tda = other.m->tda; if (Tda > 0) m->tda = Tda; m->data = other.m->data + (iStartRow * other.m->tda + iStartCol); m->block = NULL; m->owner = 0; #if GSL_RANGE_CHECK // check that the end of the view isn't past the end of the mat it is viewing const double *pEndThis = &(*this)(nrows()-1, ncols()-1); const double *pEndOther = &other(other.nrows()-1, other.ncols()-1); if (pEndOther - pEndThis < 0) { SysErr("MatView::view %dx%d tda %d (start %dx%d len %dx%d) doesn't fit into %dx%d tda %d (%d elements too big)", m->size1, m->size2, m->tda, iStartRow, iStartCol, nrows1, ncols1, other.m->size1, other.m->size2, other.m->tda, pEndThis - pEndOther); } #endif}void MatView::init (double other[], size_t iStartRow, size_t iStartCol, size_t nrows1, size_t ncols1, int Tda=0) { DASSERT(static_cast<const void *>(this) != static_cast<const void *>(&other)); #if GSL_RANGE_CHECK CheckReasonableDim(iStartRow, iStartCol, 0, "MatView bad start row %d or column %d"); CheckReasonableDim(nrows1, ncols1, 1, "MatView bad number of rows %d or columns %d"); if (iStartRow != 0 && iStartCol != 0) //TODO need to figure out sensible implementation SysErr("MatView non-zero start row %d and start col %d not yet implemented", iStartRow, iStartCol); #endif if (!m) m = (gsl_matrix *)malloc(sizeof(gsl_matrix)); m->size1 = nrows1; m->size2 = ncols1; m->tda = ncols1; if (Tda > 0) m->tda = Tda; m->data = other; m->block = NULL; m->data += iStartRow * m->tda + iStartCol; m->owner = 0; }}; // end class MatView} // end namespace GslMat#endif // matview_hpp
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -