📄 newmat3.cpp
字号:
//$$ newmat3.cpp Matrix get and restore rows and columns// Copyright (C) 1991,2,3,4: R B Davies//#define WANT_STREAM#include "include.h"#include "newmat.h"#include "newmatrc.h"#ifdef use_namespacenamespace NEWMAT {#endif#ifdef DO_REPORT#define REPORT { static ExeCounter ExeCount(__LINE__,3); ++ExeCount; }#else#define REPORT {}#endif//#define MONITOR(what,storage,store)// { cout << what << " " << storage << " at " << (long)store << "\n"; }#define MONITOR(what,store,storage) {}// Control bits codes for GetRow, GetCol, RestoreRow, RestoreCol//// LoadOnEntry:// Load data into MatrixRow or Col dummy array under GetRow or GetCol// StoreOnExit:// Restore data to original matrix under RestoreRow or RestoreCol// DirectPart:// Load or restore only part directly stored; must be set with StoreOnExit// Still have decide how to handle this with symmetric// StoreHere:// used in columns only - store data at supplied storage address;// used for GetCol, NextCol & RestoreCol. No need to fill out zeros// HaveStore:// dummy array has been assigned (internal use only).// For symmetric matrices, treat columns as rows unless StoreHere is set;// then stick to columns as this will give better performance for doing// inverses// How components are used:// Use rows wherever possible in preference to columns// Columns without StoreHere are used in in-exact transpose, sum column,// multiply a column vector, and maybe in future access to column,// additional multiply functions, add transpose// Columns with StoreHere are used in exact transpose (not symmetric matrices// or vectors, load only)// Columns with MatrixColX (Store to full column) are used in inverse and solve// Functions required for each matrix class// GetRow(MatrixRowCol& mrc)// GetCol(MatrixRowCol& mrc)// GetCol(MatrixColX& mrc)// RestoreRow(MatrixRowCol& mrc)// RestoreCol(MatrixRowCol& mrc)// RestoreCol(MatrixColX& mrc)// NextRow(MatrixRowCol& mrc)// NextCol(MatrixRowCol& mrc)// NextCol(MatrixColX& mrc)// The Restore routines assume StoreOnExit has already been checked// Defaults for the Next routines are given below// Assume cannot have both !DirectPart && StoreHere for MatrixRowCol routines// Default NextRow and NextCol:// will work as a default but need to override NextRow for efficiencyvoid GeneralMatrix::NextRow(MatrixRowCol& mrc){ REPORT if (+(mrc.cw*StoreOnExit)) { REPORT this->RestoreRow(mrc); } mrc.rowcol++; if (mrc.rowcol<nrows) { REPORT this->GetRow(mrc); } else { REPORT mrc.cw -= StoreOnExit; }}void GeneralMatrix::NextCol(MatrixRowCol& mrc){ REPORT // 423 if (+(mrc.cw*StoreOnExit)) { REPORT this->RestoreCol(mrc); } mrc.rowcol++; if (mrc.rowcol<ncols) { REPORT this->GetCol(mrc); } else { REPORT mrc.cw -= StoreOnExit; }}void GeneralMatrix::NextCol(MatrixColX& mrc){ REPORT // 423 if (+(mrc.cw*StoreOnExit)) { REPORT this->RestoreCol(mrc); } mrc.rowcol++; if (mrc.rowcol<ncols) { REPORT this->GetCol(mrc); } else { REPORT mrc.cw -= StoreOnExit; }}// routines for matrixvoid Matrix::GetRow(MatrixRowCol& mrc){ REPORT mrc.skip=0; mrc.storage=mrc.length=ncols; mrc.data=store+mrc.rowcol*ncols;}void Matrix::GetCol(MatrixRowCol& mrc){ REPORT mrc.skip=0; mrc.storage=mrc.length=nrows; if ( ncols==1 && !(mrc.cw*StoreHere) ) // ColumnVector { REPORT mrc.data=store; } else { Real* ColCopy; if ( !(mrc.cw*(HaveStore+StoreHere)) ) { REPORT ColCopy = new Real [nrows]; MatrixErrorNoSpace(ColCopy); MONITOR_REAL_NEW("Make (MatGetCol)",nrows,ColCopy) mrc.data = ColCopy; mrc.cw += HaveStore; } else { REPORT ColCopy = mrc.data; } if (+(mrc.cw*LoadOnEntry)) { REPORT Real* Mstore = store+mrc.rowcol; int i=nrows; //while (i--) { *ColCopy++ = *Mstore; Mstore+=ncols; } if (i) for (;;) { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore+=ncols; } } }}void Matrix::GetCol(MatrixColX& mrc){ REPORT mrc.skip=0; mrc.storage=nrows; mrc.length=nrows; if (+(mrc.cw*LoadOnEntry)) { REPORT Real* ColCopy = mrc.data; Real* Mstore = store+mrc.rowcol; int i=nrows; //while (i--) { *ColCopy++ = *Mstore; Mstore+=ncols; } if (i) for (;;) { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore+=ncols; } }}void Matrix::RestoreCol(MatrixRowCol& mrc){ // always check StoreOnExit before calling RestoreCol REPORT // 429 if (+(mrc.cw*HaveStore)) { REPORT // 426 Real* Mstore = store+mrc.rowcol; int i=nrows; Real* Cstore = mrc.data; // while (i--) { *Mstore = *Cstore++; Mstore+=ncols; } if (i) for (;;) { *Mstore = *Cstore++; if (!(--i)) break; Mstore+=ncols; } }}void Matrix::RestoreCol(MatrixColX& mrc){ REPORT Real* Mstore = store+mrc.rowcol; int i=nrows; Real* Cstore = mrc.data; // while (i--) { *Mstore = *Cstore++; Mstore+=ncols; } if (i) for (;;) { *Mstore = *Cstore++; if (!(--i)) break; Mstore+=ncols; }}void Matrix::NextRow(MatrixRowCol& mrc) { REPORT mrc.IncrMat(); } // 1808void Matrix::NextCol(MatrixRowCol& mrc){ REPORT // 632 if (+(mrc.cw*StoreOnExit)) { REPORT RestoreCol(mrc); } mrc.rowcol++; if (mrc.rowcol<ncols) { if (+(mrc.cw*LoadOnEntry)) { REPORT Real* ColCopy = mrc.data; Real* Mstore = store+mrc.rowcol; int i=nrows; //while (i--) { *ColCopy++ = *Mstore; Mstore+=ncols; } if (i) for (;;) { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore+=ncols; } } } else { REPORT mrc.cw -= StoreOnExit; }}void Matrix::NextCol(MatrixColX& mrc){ REPORT if (+(mrc.cw*StoreOnExit)) { REPORT RestoreCol(mrc); } mrc.rowcol++; if (mrc.rowcol<ncols) { if (+(mrc.cw*LoadOnEntry)) { REPORT Real* ColCopy = mrc.data; Real* Mstore = store+mrc.rowcol; int i=nrows; // while (i--) { *ColCopy++ = *Mstore; Mstore+=ncols; } if (i) for (;;) { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore+=ncols; } } } else { REPORT mrc.cw -= StoreOnExit; }}// routines for diagonal matrixvoid DiagonalMatrix::GetRow(MatrixRowCol& mrc){ REPORT mrc.skip=mrc.rowcol; mrc.storage=1; mrc.data=store+mrc.skip; mrc.length=ncols;}void DiagonalMatrix::GetCol(MatrixRowCol& mrc){ REPORT mrc.skip=mrc.rowcol; mrc.storage=1; mrc.length=nrows; if (+(mrc.cw*StoreHere)) // should not happen Throw(InternalException("DiagonalMatrix::GetCol(MatrixRowCol&)")); else { REPORT mrc.data=store+mrc.skip; } // not accessed}void DiagonalMatrix::GetCol(MatrixColX& mrc){ REPORT mrc.skip=mrc.rowcol; mrc.storage=1; mrc.length=nrows; mrc.data = mrc.store+mrc.skip; *(mrc.data)=*(store+mrc.skip);}void DiagonalMatrix::NextRow(MatrixRowCol& mrc) { REPORT mrc.IncrDiag(); } // 800void DiagonalMatrix::NextCol(MatrixRowCol& mrc) { REPORT mrc.IncrDiag(); } // not accessedvoid DiagonalMatrix::NextCol(MatrixColX& mrc){ REPORT if (+(mrc.cw*StoreOnExit)) { REPORT *(store+mrc.rowcol)=*(mrc.data); } mrc.IncrDiag(); int t1 = +(mrc.cw*LoadOnEntry); if (t1 && mrc.rowcol < ncols) { REPORT *(mrc.data)=*(store+mrc.rowcol); }}// routines for upper triangular matrixvoid UpperTriangularMatrix::GetRow(MatrixRowCol& mrc){ REPORT int row = mrc.rowcol; mrc.skip=row; mrc.length=ncols; mrc.storage=ncols-row; mrc.data=store+(row*(2*ncols-row+1))/2;}void UpperTriangularMatrix::GetCol(MatrixRowCol& mrc){ REPORT mrc.skip=0; int i=mrc.rowcol+1; mrc.storage=i; mrc.length=nrows; Real* ColCopy; if ( !(mrc.cw*(StoreHere+HaveStore)) ) { REPORT // not accessed ColCopy = new Real [nrows]; MatrixErrorNoSpace(ColCopy); MONITOR_REAL_NEW("Make (UT GetCol)",nrows,ColCopy) mrc.data = ColCopy; mrc.cw += HaveStore; } else { REPORT ColCopy = mrc.data; } if (+(mrc.cw*LoadOnEntry)) { REPORT Real* Mstore = store+mrc.rowcol; int j = ncols; // while (i--) { *ColCopy++ = *Mstore; Mstore += --j; } if (i) for (;;) { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += --j; } }}void UpperTriangularMatrix::GetCol(MatrixColX& mrc){ REPORT mrc.skip=0; int i=mrc.rowcol+1; mrc.storage=i; mrc.length=nrows; if (+(mrc.cw*LoadOnEntry)) { REPORT Real* ColCopy = mrc.data; Real* Mstore = store+mrc.rowcol; int j = ncols; // while (i--) { *ColCopy++ = *Mstore; Mstore += --j; } if (i) for (;;) { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += --j; } }}void UpperTriangularMatrix::RestoreCol(MatrixRowCol& mrc){ REPORT Real* Mstore = store+mrc.rowcol; int i=mrc.rowcol+1; int j = ncols; Real* Cstore = mrc.data; // while (i--) { *Mstore = *Cstore++; Mstore += --j; } if (i) for (;;) { *Mstore = *Cstore++; if (!(--i)) break; Mstore += --j; }}void UpperTriangularMatrix::NextRow(MatrixRowCol& mrc) { REPORT mrc.IncrUT(); } // 722// routines for lower triangular matrixvoid LowerTriangularMatrix::GetRow(MatrixRowCol& mrc){ REPORT int row=mrc.rowcol; mrc.skip=0; mrc.storage=row+1; mrc.length=ncols; mrc.data=store+(row*(row+1))/2;}void LowerTriangularMatrix::GetCol(MatrixRowCol& mrc){ REPORT int col=mrc.rowcol; mrc.skip=col; mrc.length=nrows; int i=nrows-col; mrc.storage=i; Real* ColCopy; if ( +(mrc.cw*(StoreHere+HaveStore)) ) { REPORT ColCopy = mrc.data; } else { REPORT // not accessed ColCopy = new Real [nrows]; MatrixErrorNoSpace(ColCopy); MONITOR_REAL_NEW("Make (LT GetCol)",nrows,ColCopy) mrc.cw += HaveStore; mrc.data = ColCopy; } if (+(mrc.cw*LoadOnEntry)) { REPORT Real* Mstore = store+(col*(col+3))/2; // while (i--) { *ColCopy++ = *Mstore; Mstore += ++col; } if (i) for (;;) { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += ++col; } }}void LowerTriangularMatrix::GetCol(MatrixColX& mrc){ REPORT int col=mrc.rowcol; mrc.skip=col; mrc.length=nrows; int i=nrows-col; mrc.storage=i; mrc.data = mrc.store + col; if (+(mrc.cw*LoadOnEntry)) { REPORT Real* ColCopy = mrc.data; Real* Mstore = store+(col*(col+3))/2; // while (i--) { *ColCopy++ = *Mstore; Mstore += ++col; } if (i) for (;;) { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += ++col; } }}void LowerTriangularMatrix::RestoreCol(MatrixRowCol& mrc){ REPORT int col=mrc.rowcol; Real* Cstore = mrc.data; Real* Mstore = store+(col*(col+3))/2; int i=nrows-col; //while (i--) { *Mstore = *Cstore++; Mstore += ++col; } if (i) for (;;) { *Mstore = *Cstore++; if (!(--i)) break; Mstore += ++col; }}void LowerTriangularMatrix::NextRow(MatrixRowCol& mrc) { REPORT mrc.IncrLT(); } //712// routines for symmetric matrixvoid SymmetricMatrix::GetRow(MatrixRowCol& mrc){ REPORT //571 mrc.skip=0; int row=mrc.rowcol; mrc.length=ncols; if (+(mrc.cw*DirectPart)) { REPORT mrc.storage=row+1; mrc.data=store+(row*(row+1))/2; } else { // do not allow StoreOnExit and !DirectPart if (+(mrc.cw*StoreOnExit)) Throw(InternalException("SymmetricMatrix::GetRow(MatrixRowCol&)")); mrc.storage=ncols; Real* RowCopy; if (!(mrc.cw*HaveStore)) { REPORT RowCopy = new Real [ncols]; MatrixErrorNoSpace(RowCopy); MONITOR_REAL_NEW("Make (SymGetRow)",ncols,RowCopy) mrc.cw += HaveStore; mrc.data = RowCopy; } else { REPORT RowCopy = mrc.data; } if (+(mrc.cw*LoadOnEntry)) { REPORT // 544 Real* Mstore = store+(row*(row+1))/2; int i = row; while (i--) *RowCopy++ = *Mstore++; i = ncols-row;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -