/// \ingroup newmat ///@{ /// \file newmatrc.h /// Header file for row/column classes // Copyright (C) 1991,2,3,4,7: R B Davies #ifndef NEWMATRC_LIB #define NEWMATRC_LIB 0 #ifdef use_namespace namespace NEWMAT { #endif #include "controlw.h" /************** classes MatrixRowCol, MatrixRow, MatrixCol *****************/ // Used for accessing the rows and columns of matrices // All matrix classes must provide routines for calculating matrix rows and // columns. Assume rows can be found very efficiently. enum LSF { LoadOnEntry=1,StoreOnExit=2,DirectPart=4,StoreHere=8,HaveStore=16 }; /// Option for accessing row or column. /// \internal class LoadAndStoreFlag : public ControlWord { public: LoadAndStoreFlag() {} LoadAndStoreFlag(int i) : ControlWord(i) {} LoadAndStoreFlag(LSF lsf) : ControlWord(lsf) {} LoadAndStoreFlag(const ControlWord& cwx) : ControlWord(cwx) {} }; /// Access a row or column of a matrix. /// \internal class MatrixRowCol { public: // these are public to avoid // numerous friend statements int length; // row or column length int skip; // initial number of zeros int storage; // number of stored elements int rowcol; // row or column number GeneralMatrix* gm; // pointer to parent matrix Real* data; // pointer to local storage LoadAndStoreFlag cw; // Load? Store? Is a Copy? void IncrMat() { rowcol++; data += storage; } // used by NextRow void IncrDiag() { rowcol++; skip++; data++; } void IncrId() { rowcol++; skip++; } void IncrUT() { rowcol++; data += storage; storage--; skip++; } void IncrLT() { rowcol++; data += storage; storage++; } public: void Zero(); // set elements to zero void Add(const MatrixRowCol&); // add a row/col void AddScaled(const MatrixRowCol&, Real); // add a multiple of a row/col void Add(const MatrixRowCol&, const MatrixRowCol&); // add two rows/cols void Add(const MatrixRowCol&, Real); // add a row/col void NegAdd(const MatrixRowCol&, Real); // Real - a row/col void Sub(const MatrixRowCol&); // subtract a row/col void Sub(const MatrixRowCol&, const MatrixRowCol&); // sub a row/col from another void RevSub(const MatrixRowCol&); // subtract from a row/col void ConCat(const MatrixRowCol&, const MatrixRowCol&); // concatenate two row/cols void Multiply(const MatrixRowCol&); // multiply a row/col void Multiply(const MatrixRowCol&, const MatrixRowCol&); // multiply two row/cols void KP(const MatrixRowCol&, const MatrixRowCol&); // Kronecker Product two row/cols void Copy(const MatrixRowCol&); // copy a row/col void CopyCheck(const MatrixRowCol&); // ... check for data loss void Check(const MatrixRowCol&); // just check for data loss void Check(); // check full row/col present void Copy(const double*&); // copy from an array void Copy(const float*&); // copy from an array void Copy(const int*&); // copy from an array void Copy(Real); // copy from constant void Add(Real); // add a constant void Multiply(Real); // multiply by constant Real SumAbsoluteValue(); // sum of absolute values Real MaximumAbsoluteValue1(Real r, int& i); // maximum of absolute values Real MinimumAbsoluteValue1(Real r, int& i); // minimum of absolute values Real Maximum1(Real r, int& i); // maximum Real Minimum1(Real r, int& i); // minimum Real Sum(); // sum of values void Inject(const MatrixRowCol&); // copy stored els of a row/col void Negate(const MatrixRowCol&); // change sign of a row/col void Multiply(const MatrixRowCol&, Real); // scale a row/col friend Real DotProd(const MatrixRowCol&, const MatrixRowCol&); // sum of pairwise product Real* Data() { return data; } int Skip() { return skip; } // number of elements skipped int Storage() { return storage; } // number of elements stored int Length() { return length; } // length of row or column void Skip(int i) { skip=i; } void Storage(int i) { storage=i; } void Length(int i) { length=i; } void SubRowCol(MatrixRowCol&, int, int) const; // get part of a row or column MatrixRowCol() {} // to stop warning messages ~MatrixRowCol(); FREE_CHECK(MatrixRowCol) }; /// Access a row of a matrix. /// \internal class MatrixRow : public MatrixRowCol { public: // bodies for these are inline at the end of this .h file MatrixRow(GeneralMatrix*, LoadAndStoreFlag, int=0); // extract a row ~MatrixRow(); void Next(); // get next row FREE_CHECK(MatrixRow) }; /// Access a column of a matrix. /// \internal class MatrixCol : public MatrixRowCol { public: // bodies for these are inline at the end of this .h file MatrixCol(GeneralMatrix*, LoadAndStoreFlag, int=0); // extract a col MatrixCol(GeneralMatrix*, Real*, LoadAndStoreFlag, int=0); // store/retrieve a col ~MatrixCol(); void Next(); // get next column FREE_CHECK(MatrixCol) }; /// Alternative to MatrixCol where the complete column is stored externally. /// \internal class MatrixColX : public MatrixRowCol { public: // bodies for these are inline at the end of this .h file MatrixColX(GeneralMatrix*, Real*, LoadAndStoreFlag, int=0); // store/retrieve a col ~MatrixColX(); void Next(); // get next row Real* store; // pointer to local storage // less skip FREE_CHECK(MatrixColX) }; /**************************** inline bodies ****************************/ inline MatrixRow::MatrixRow(GeneralMatrix* gmx, LoadAndStoreFlag cwx, int row) { gm=gmx; cw=cwx; rowcol=row; gm->GetRow(*this); } inline void MatrixRow::Next() { gm->NextRow(*this); } inline MatrixCol::MatrixCol(GeneralMatrix* gmx, LoadAndStoreFlag cwx, int col) { gm=gmx; cw=cwx; rowcol=col; gm->GetCol(*this); } inline MatrixCol::MatrixCol(GeneralMatrix* gmx, Real* r, LoadAndStoreFlag cwx, int col) { gm=gmx; data=r; cw=cwx+StoreHere; rowcol=col; gm->GetCol(*this); } inline MatrixColX::MatrixColX(GeneralMatrix* gmx, Real* r, LoadAndStoreFlag cwx, int col) { gm=gmx; store=data=r; cw=cwx+StoreHere; rowcol=col; gm->GetCol(*this); } inline void MatrixCol::Next() { gm->NextCol(*this); } inline void MatrixColX::Next() { gm->NextCol(*this); } #ifdef use_namespace } #endif #endif ///@}