// --- Special Square matrices base class // This code is part of the SOPHYA library // (C) Univ. Paris-Sud (C) LAL-IN2P3/CNRS (C) IRFU-CEA // (C) R. Ansari, C.Magneville 2009 #define SPESQMTX_CC_BFILE // avoid extern template declarations #include "spesqmtx.h" #include "pexceptions.h" #include "tmatrix.h" namespace SOPHYA { /*! \class SpecialSquareMatrix \ingroup TArray \brief The base class for representing and manipulating special square matrices Diagonal matrix, Symmetric matrix, Triangular matrix This class implements the common operations for special square matrices. Only objects from the sub-classes (DiagonalMatrix, LowerTriangularMatrix, SymmetricMatrix) can be instanciated. Theses classes offer similar functionalities to the TArray / TMatrix classes, like reference sharing and arithmetic operations. However, no sub-matrix extraction method is provided. \code // Create and initialize a diagonal matrix DiagonalMatrix diag(3); diag(0,0)=1.; diag(1,1)=2.; diag(2,2)=3.; // use of multiplication by a constant operator diag *= 10.; // check the diagonal matrix cout << diag << diag.ConvertToStdMatrix() << endl; // define and initialize a general matrix TMatrix mx(3,3); mx=RegularSequence(); cout << mx; // check the result of a matrix mutiplication cout << mx*diag; \endcode */ //! Default constructor - SpecialSquareMatrix of size 0, SetSize() should be called before the object is used template SpecialSquareMatrix::SpecialSquareMatrix(SpSqMtxType typ) : mType(typ) , mNrows(0) , mInfo(NULL) { } //! Instanciate a SpecialSquareMatrix matrix from the number of rows (rowSize must be > 0) template SpecialSquareMatrix::SpecialSquareMatrix(sa_size_t rowSize, SpSqMtxType typ) : mType(typ) , mNrows(rowSize) , mInfo(NULL) { if (rowSize < 1) throw ParmError("SpecialSquareMatrix::SpecialSquareMatrix(rsz) rsz <= 0"); } //! Copy constructor (possibility of sharing datas) template SpecialSquareMatrix::SpecialSquareMatrix(SpecialSquareMatrix const & a, bool share) : mType(a.mType) , mNrows(a.mNrows) , mElems(a.mElems, share) , mInfo(NULL) { if (a.mInfo) mInfo = new DVList(*(a.mInfo)); } //! Sets or change the matrix size, specifying the new number of rows template void SpecialSquareMatrix::SetSize(sa_size_t rowSize) { throw ForbiddenError("SpecialSquareMatrix::SetSize() Only sub-classes should be instanciated"); } //! Return the object as a standard (TMatrix) object template TMatrix SpecialSquareMatrix::ConvertToStdMatrix() const { throw ForbiddenError("SpecialSquareMatrix::ConvertToStdMatrix() Only sub-classes should be instanciated"); } //! Clone (duplicate) the SpecialSquareMatrix matrix \b a template void SpecialSquareMatrix::Clone(SpecialSquareMatrix const & a) { if ((mType != C_UndefinedMatrix) && (a.mType != mType)) throw TypeMismatchExc("SpecialSquareMatrix::Clone()- Different type matrices"); mType = a.mType; mNrows = a.mNrows; mElems.Clone(a.mElems); if (a.mInfo) mInfo = new DVList(*(a.mInfo)); } //! Share the data with \b a template void SpecialSquareMatrix::Share(SpecialSquareMatrix const & a) { if ((mType != C_UndefinedMatrix) && (a.mType != mType)) throw TypeMismatchExc("SpecialSquareMatrix::Share()- Different type matrices"); mType = a.mType; mNrows= a.mNrows; mElems.Share(a.mElems); if (a.mInfo) mInfo = new DVList(*(a.mInfo)); } //! Clone or share the data. Data is shared if \b is flagged as temporary template void SpecialSquareMatrix::CloneOrShare(SpecialSquareMatrix const & a) { if ((mType != C_UndefinedMatrix) && (a.mType != mType)) throw TypeMismatchExc("SpecialSquareMatrix::CloneOrShare()- Different type matrices"); mType = a.mType; mNrows = a.mNrows; mElems.CloneOrShare(a.mElems); if (a.mInfo) mInfo = new DVList(*(a.mInfo)); } //! Set all matrix elements to the value \b a template SpecialSquareMatrix& SpecialSquareMatrix::SetCst(T a) { if (mElems.Size() < 1) throw SzMismatchError("SpecialSquareMatrix::SetCst(T )- (this) not allocated !"); mElems = a; return (*this); } //! Element by element copy method template SpecialSquareMatrix& SpecialSquareMatrix::Set(SpecialSquareMatrix const & a) { if (a.mType != mType) throw TypeMismatchExc("SpecialSquareMatrix::Set(a)- Different type matrices"); if (a.mElems.Size() < 1) throw SzMismatchError("SpecialSquareMatrix::Set(a)- Object a not allocated !"); if (mElems.Size() < 1) { mNrows = a.mNrows; mElems.CloneOrShare(a.mElems); return (*this); } if (mNrows != a.mNrows) throw SzMismatchError("SpecialSquareMatrix::Set(a)- NRows() != a.NRows() ! "); mElems = a.mElems; return (*this); } //! Set the matrix elements using the values from the sequence \b seq template SpecialSquareMatrix& SpecialSquareMatrix::SetSeq(Sequence const & seq) { if (mElems.Size() < 1) throw SzMismatchError("SpecialSquareMatrix::SetSeq()- (this) not allocated !"); for(size_t k=0; k SpecialSquareMatrix& SpecialSquareMatrix::AddCst(T b) { if (mElems.Size() < 1) throw SzMismatchError("SpecialSquareMatrix::AddCst(T )- (this) not allocated !"); mElems += b; return (*this); } //! Subtract a constant value (\b b ) from all matrix elements. fginv==true -> elem = b-elem template SpecialSquareMatrix& SpecialSquareMatrix::SubCst(T b, bool fginv) { if (mElems.Size() < 1) throw SzMismatchError("SpecialSquareMatrix::Subst(T )- (this) not allocated !"); if (fginv) mElems = mElems.Sub(b, true); else mElems -= b; return (*this); } //! Multiply all matrix elements by a constant value \b b . template SpecialSquareMatrix& SpecialSquareMatrix::MulCst(T b) { if (mElems.Size() < 1) throw SzMismatchError("SpecialSquareMatrix::MulCst(T )- (this) not allocated !"); mElems *= b; return (*this); } //! Divide all matrix elements by a constant value \b b . if fginv==true elem = b / elem template SpecialSquareMatrix& SpecialSquareMatrix::DivCst(T b, bool fginv) { if (mElems.Size() < 1) throw SzMismatchError("SpecialSquareMatrix::DivCst(T )- (this) not allocated !"); if (fginv) mElems = mElems.Div(b, true); else mElems /= b; return (*this); } //! Element by element addition : elem(l,m) = elem(l,m) + b.elem(l,m) template SpecialSquareMatrix& SpecialSquareMatrix::AddElt(SpecialSquareMatrix const& b) { if (b.mType != mType) throw TypeMismatchExc("SpecialSquareMatrix::AddElt() Different type matrices"); if ((mNrows < 1)||(mNrows != b.mNrows)||(mElems.Size() < 1)||(mElems.Size() != b.mElems.Size())) throw SzMismatchError("SpecialSquareMatrix::AddElt()- Not allocated or different sizes !"); mElems += b.mElems; return (*this); } //! Element by element subtraction : elem(l,m) = elem(l,m) - b.elem(l,m) template SpecialSquareMatrix& SpecialSquareMatrix::SubElt(SpecialSquareMatrix const& b) { if (b.mType != mType) throw TypeMismatchExc("SpecialSquareMatrix::SubElt() Different type matrices"); if ((mNrows < 1)||(mNrows != b.mNrows)||(mElems.Size() < 1)||(mElems.Size() != b.mElems.Size())) throw SzMismatchError("SpecialSquareMatrix::SubElt()- Not allocated or different sizes !"); mElems -= b.mElems; return (*this); } //! Element by element multiplication : elem(l,m) = elem(l,m) * b.elem(l,m) template SpecialSquareMatrix& SpecialSquareMatrix::MulElt(SpecialSquareMatrix const& b) { if (b.mType != mType) throw TypeMismatchExc("SpecialSquareMatrix::MulElt() Different type matrices"); if ((mNrows < 1)||(mNrows != b.mNrows)||(mElems.Size() < 1)||(mElems.Size() != b.mElems.Size())) throw SzMismatchError("SpecialSquareMatrix::MulElt()- Not allocated or different sizes !"); mElems *= b.mElems; return (*this); } //! Element by element divison : elem(l,m) = elem(l,m) / b.elem(l,m) template SpecialSquareMatrix& SpecialSquareMatrix::DivElt(SpecialSquareMatrix const& b) { if (b.mType != mType) throw TypeMismatchExc("SpecialSquareMatrix::DivElt() Different type matrices"); if ((mNrows < 1)||(mNrows != b.mNrows)||(mElems.Size() < 1)||(mElems.Size() != b.mElems.Size())) throw SzMismatchError("SpecialSquareMatrix::DivElt()- Not allocated or different sizes !"); mElems /= b.mElems; return (*this); } //! Return the minimum and the maximum values of the SpecialSquare Matrix elements /*! This method generates an exception (\c MathExc) if called for complex matrices */ template void SpecialSquareMatrix::MinMax(T& min, T& max) const { const T * pe = mElems.Begin(); min = pe[0]; max = pe[0]; for(size_t k=0; kmax) max = pe[k]; } return; } DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */ void SpecialSquareMatrix< complex >::MinMax(complex& min, complex& max) const { throw MathExc("SpecialSquareMatrix< complex >::MinMax(...) - No order in complex"); } DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */ void SpecialSquareMatrix< complex >::MinMax(complex& min, complex& max) const { throw MathExc("SpecialSquareMatrix< complex >::MinMax(...) - No order in complex"); } //! Short ASCII representatio of the object pushed to stream \b os template ostream& SpecialSquareMatrix::Show(ostream& os) const { os << typeid(*this).name() << " < " << typeid(T).name() << " > NRow=" << mNrows << " NbElem<>0 : " << Size() << endl; return os; } /////////////////////////////////////////////////////////////// #ifdef __CXX_PRAGMA_TEMPLATES__ #pragma define_template SpecialSquareMatrix #pragma define_template SpecialSquareMatrix #pragma define_template SpecialSquareMatrix #pragma define_template SpecialSquareMatrix #pragma define_template SpecialSquareMatrix #pragma define_template SpecialSquareMatrix #pragma define_template SpecialSquareMatrix #pragma define_template SpecialSquareMatrix #pragma define_template SpecialSquareMatrix #pragma define_template SpecialSquareMatrix #pragma define_template SpecialSquareMatrix< complex > #pragma define_template SpecialSquareMatrix< complex > #ifdef SO_LDBLE128 #pragma define_template SpecialSquareMatrix #pragma define_template SpecialSquareMatrix< complex > #endif #endif #if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES) template class SpecialSquareMatrix; template class SpecialSquareMatrix; template class SpecialSquareMatrix; template class SpecialSquareMatrix; template class SpecialSquareMatrix; template class SpecialSquareMatrix; template class SpecialSquareMatrix; template class SpecialSquareMatrix; template class SpecialSquareMatrix; template class SpecialSquareMatrix; template class SpecialSquareMatrix< complex >; template class SpecialSquareMatrix< complex >; #ifdef SO_LDBLE128 template class SpecialSquareMatrix; template class SpecialSquareMatrix< complex >; #endif #endif } // namespace SOPHYA