/////////////////////////////////////////////////////////////////////////////// // // // The Template Matrix/Vector Library for C++ was created by Mike Jarvis // // Copyright (C) 1998 - 2016 // // All rights reserved // // // // The project is hosted at https://code.google.com/p/tmv-cpp/ // // where you can find the current version and current documention. // // // // For concerns or problems with the software, Mike may be contacted at // // mike_jarvis17 [at] gmail. // // // // This software is licensed under a FreeBSD license. The file // // TMV_LICENSE should have bee included with this distribution. // // It not, you can get a copy from https://code.google.com/p/tmv-cpp/. // // // // Essentially, you can use this software however you want provided that // // you include the TMV_LICENSE file in any distribution that uses it. // // // /////////////////////////////////////////////////////////////////////////////// //--------------------------------------------------------------------------- // // This file defines the TMV SymMatrix and HermMatrix classes. // // SymMatrix is used for symmetric matrices, and // HermMatrix is used for Hermitian matrices. // For real matrices, these are the same thing: // A = A.transpose(). // But for complex, they are different: // A_sym = A_sym.transpose() // A_herm = A_herm.adjoint() // // For these notes, I will always write SymMatrix, but (except where // otherwise indicated) everything applies the same for Sym and Herm. // Also, the Views keep track of sym/herm difference with a parameter, // so it is always a GenSymMatrix, ConstSymMatrixView, or // SymMatrixView - never Herm in any of these. // // Caveat: Complex Hermitian matrices are such that A = At, which // implies that their diagonal elements are real. Many routines // involving HermMatrixes assume the reality of the diagonal. // However, it is possible to assign a non-real value to a diagonal // element. If the user does this, the results are undefined. // // As usual, the first template parameter is the type of the data, // and the optional second template parameter specifies the known // attributes. The valid attributs for a SymMatrix are: // - ColMajor or RoMajor // - CStyle or FortranStyle // - Lower or Upper // The defaults are (ColMajor,CStyle,Lower) if you do not specify // otherwise. // // The storage and index style follow the same meaning as for regular // Matrices. // Lower or Upper refers to which triangular half stores the actual data. // // Constructors: // // SymMatrix(int n) // Makes a Symmetric Matrix with column size = row size = n // with _uninitialized_ values. // // SymMatrix(int n, T x) // Makes a Symmetric Matrix with values all initialized to x // For Hermitian matrixces, x must be real. // // SymMatrix(const Matrix& m) // Makes a SymMatrix which copies the corresponding elements of m. // // ConstSymMatrixView SymMatrixViewOf(const Matrix& m, uplo) // ConstSymMatrixView HermMatrixViewOf(const Matrix& m, uplo) // Makes a constant SymMatrix view of the corresponding part of m. // While this view cannot be modified, changing the original m // will cause corresponding changes in this view of m. // // SymMatrixView SymMatrixViewOf(Matrix& m, uplo) // SymMatrixView HermMatrixViewOf(Matrix& m, uplo) // Makes a modifiable SymMatrix view of the corresponding part of m. // Modifying this matrix will change the corresponding elements in // the original Matrix. // // ConstSymMatrixView SymMatrixViewOf(const T* m, size, uplo, stor) // ConstSymMatrixView HermMatrixViewOf(const T* m, size, uplo, stor) // SymMatrixView SymMatrixViewOf(T* m, size, uplo, stor) // SymMatrixView HermMatrixViewOf(T* m, size, uplo, stor) // View the actual memory pointed to by m as a SymMatrix/HermMatrix // with the given size and storage. // // Access Functions // // int colsize() const // int rowsize() const // int size() const // Return the dimensions of the SymMatrix // // T& operator()(int i, int j) // T operator()(int i, int j) const // Return the (i,j) element of the SymMatrix // // Vector& row(int i, int j1, int j2) // Return a portion of the ith row // This range must be a valid range for the requested row // and be entirely in the upper or lower triangle. // // Vector& col(int j, int i1, int i2) // Return a portion of the jth column // This range must be a valid range for the requested column // and be entirely in the upper or lower triangle. // // Vector& diag() // Return the main diagonal // // Vector& diag(int i, int j1, int j2) // Vector& diag(int i) // Return the super- or sub-diagonal i // If i > 0 return the super diagonal starting at m_0i // If i < 0 return the sub diagonal starting at m_|i|0 // If j1,j2 are given, it returns the diagonal Vector // either from m_j1,i+j1 to m_j2,i+j2 (for i>0) // or from m_|i|+j1,j1 to m_|i|+j2,j2 (for i<0) // // Modifying Functions: // // setZero() // setAllTo(T x) // addToAll(T x) // For HermMatrix, x must be real in both setAllTo and addToAll. // clip(RT thresh) // conjugateSelf() // transposeSelf() // setToIdentity(x = 1) // swapRowsCols(i1,i2) // Equivalent to swapping rows i1,i2 then swapping cols i1,i2. // permuteRowsCols(const int* p) // reversePermuteRowsCols(const int* p) // Perform a series of row/col swaps. // void Swap(SymMatrix& m1, SymMatrix& m2) // The SymMatrices must be the same size and Hermitianity. // // Views of a SymMatrix: // // subMatrix(int i1, int i2, int j1, int j2, int istep=1, int jstep=1) // This member function will return a submatrix using rows i1 to i2 // and columns j1 to j2 which refers // to the same physical elements as the original. // The submatrix must be completely contained within the upper // or lower triangle. // // subVector(int i, int j, int istep, int jstep, int size) // Returns a VectorView which starts at position (i,j) in the // matrix, moves in the directions (istep,jstep) and has a length // of size. The subvector must be completely with the upper or // lower triangle. // // subSymMatrix(int i1, int i2, int istep) // Returns the SymMatrix which runs from i1 to i2 along the diagonal // (not including i2) with an optional step, and includes the // off diagonal in the same rows/cols. // // For example, with a SymMatrix of size 10, the x's below // are the original data, the O's are the subSymMatrix returned // with the command subSymMatrix(3,11,2), and the #'s are the // subSymMatrix returned with subSymMatrix(0,3) // // ###xxxxxxx // ###xxxxxxx // ###xxxxxxx // xxxOxOxOxO // xxxxxxxxxx // xxxOxOxOxO // xxxxxxxxxx // xxxOxOxOxO // xxxxxxxxxx // xxxOxOxOxO // // transpose(m) // adjoint(m) // conjugate(m) // // // Functions of Matrixs: // // m.det() or Det(m) // m.logDet() or m.logDet(T* sign) or LogDet(m) // m.trace() or Trace(m) // m.sumElements() or SumElements(m) // m.sumAbsElements() or SumAbsElements(m) // m.sumAbs2Elements() or SumAbs2Elements(m) // m.norm() or m.normF() or Norm(m) or NormF(m) // m.normSq() or NormSq(m) // m.norm1() or Norm1(m) // m.norm2() or Norm2(m) // m.normInf() or NormInf(m) // m.maxAbsElement() or MaxAbsElements(m) // m.maxAbs2Element() or MaxAbs2Elements(m) // // m.inverse() or Inverse(m) // m.makeInverse(minv) // Takes either a SymMatrix or Matrix argument // m.makeInverseATA(invata) // // // I/O: // // os << m // Writes m to ostream os in the usual Matrix format // // os << CompactIO() << m // Writes m to ostream os in the following compact format: // size // ( m(0,0) ) // ( m(1,0) m(1,1) ) // ... // ( m(size-1,0) ... m(size-1,size-1) ) // // is >> m // is >> CompactIO() >> m // Reads m from istream is in either format // // // Division Control Functions: // // m.divideUsing(dt) // where dt is LU, CH, or SV // // m.lud(), m.chd(), m.svd(), and m.symsvd() return the // corresponding Divider classes. // // For SymMatrixes, LU actually does an LDLT decomposition. // ie. L(Lower Triangle) * Diagonal * L.transpose() // For non-positive definite matrices, D may have 2x2 blocks along // the diagonal, which can then be further decomposed via normal LU // decomposition. // // The option unique to hermitian matrixes is CH - Cholskey decomposition. // This is only appropriate if you know that your HermMatrix is // positive definite (ie. all eigenvalues are positive). // (This is guaranteed, for example, if all the square // submatrices have positive determinant.) // In this case, the SymMatrix can be decomposed into L*L.adjoint(). // // Finally, a difference for the SV Decomposition for Hermitian matrices // is that the decomposition can be done with V = Ut. In this case, // the "singular values" are really the eigenvalues of A. // The only caveat is that they may be negative, whereas the usual // definition of singular values is that they are all positive. // Requiring positivity would destroy V = Ut, so it seemed more // useful to leave them as the actual eigenvalues. Just keep that // in mind if you use the singular values for anything that expects // them to be positive. // // If m is complex, symmetric (i.e. not hermitian), then the SVD // does not result in an eigenvalue decomposition, and we actually // just do a regular SVD. In this case, the access is through // symsvd(), rather than the usual svd() method. #ifndef TMV_SymMatrix_H #define TMV_SymMatrix_H #include "tmv/TMV_BaseSymMatrix.h" #include "tmv/TMV_BaseTriMatrix.h" #include "tmv/TMV_BaseDiagMatrix.h" #include "tmv/TMV_SymMatrixArithFunc.h" #include "tmv/TMV_TriMatrix.h" #include "tmv/TMV_Matrix.h" #include "tmv/TMV_DiagMatrix.h" #include "tmv/TMV_Array.h" #include namespace tmv { template class OProdVV; template class ProdMM; template class ProdUL; template class ProdLU; template struct SymCopyHelper // real { typedef SymMatrix type; }; template struct SymCopyHelper > // complex // Have to copy to matrix, since don't know whether herm or sym. { typedef Matrix > type; }; template class GenSymMatrix : virtual public AssignableToSymMatrix, public BaseMatrix, public DivHelper { public: typedef TMV_RealType(T) RT; typedef TMV_ComplexType(T) CT; typedef T value_type; typedef RT real_type; typedef CT complex_type; typedef GenSymMatrix type; typedef typename SymCopyHelper::type copy_type; typedef ConstSymMatrixView const_view_type; typedef const_view_type const_transpose_type; typedef const_view_type const_conjugate_type; typedef const_view_type const_adjoint_type; typedef ConstVectorView const_vec_type; typedef ConstMatrixView const_rec_type; typedef ConstUpperTriMatrixView const_uppertri_type; typedef ConstLowerTriMatrixView const_lowertri_type; typedef ConstSymMatrixView const_realpart_type; typedef SymMatrixView nonconst_type; // // Constructors // inline GenSymMatrix() {} inline GenSymMatrix(const type&) {} virtual inline ~GenSymMatrix() {} // // Access Functions // using AssignableToSymMatrix::size; inline ptrdiff_t colsize() const { return size(); } inline ptrdiff_t rowsize() const { return size(); } using AssignableToSymMatrix::sym; inline T operator()(ptrdiff_t i, ptrdiff_t j) const { TMVAssert(i>=0 && i=0 && j=0 && i=0 && j1-j2<=0 && j2<=size()); if ((i-j1<=0 && uplo()==Upper) || (j2-i<=1 && uplo()==Lower)) return const_vec_type( cptr()+i*stepi()+j1*stepj(),j2-j1,stepj(), ct()); else return const_vec_type( cptr()+i*stepj()+j1*stepi(),j2-j1,stepi(), issym()?ct():TMV_ConjOf(T,ct())); } inline const_vec_type col(ptrdiff_t j, ptrdiff_t i1, ptrdiff_t i2) const { TMVAssert(j>=0 && j=0 && i1-i2<=0 && i2<=size()); if ((i2-j<=1 && uplo()==Upper) || (j-i1<=0 && uplo()==Lower)) return const_vec_type( cptr()+i1*stepi()+j*stepj(),i2-i1,stepi(), ct()); else return const_vec_type( cptr()+i1*stepj()+j*stepi(),i2-i1,stepj(), issym()?ct():TMV_ConjOf(T,ct())); } inline const_vec_type diag() const { return const_vec_type( cptr(),size(),stepi()+stepj(),ct()); } inline const_vec_type diag(ptrdiff_t i) const { TMVAssert(i>=-size() && i<=size()); if (i>=0) if (uplo()==Upper) return const_vec_type( cptr()+i*stepj(),size()-i, stepi()+stepj(),ct()); else return const_vec_type( cptr()+i*stepi(),size()-i, stepi()+stepj(),issym()?ct():TMV_ConjOf(T,ct())); else if (uplo()==Upper) return const_vec_type( cptr()-i*stepj(),size()+i, stepi()+stepj(),issym()?ct():TMV_ConjOf(T,ct())); else return const_vec_type( cptr()-i*stepi(),size()+i, stepi()+stepj(),ct()); } inline const_vec_type diag(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2) const { TMVAssert(i>=-size() && i<=size()); TMVAssert(j1>=0 && j1-j2<=0 && j2<=size()-std::abs(i)); const ptrdiff_t ds = stepi()+stepj(); if (i>=0) if (uplo()==Upper) return const_vec_type( cptr()+i*stepj()+j1*ds,j2-j1,ds,ct()); else return const_vec_type( cptr()+i*stepi()+j1*ds,j2-j1,ds, issym()?ct():TMV_ConjOf(T,ct())); else if (uplo()==Upper) return const_vec_type( cptr()-i*stepj()+j1*ds,j2-j1,ds, issym()?ct():TMV_ConjOf(T,ct())); else return const_vec_type( cptr()-i*stepi()+j1*ds,j2-j1,ds,ct()); } template inline bool isSameAs(const BaseMatrix& ) const { return false; } inline bool isSameAs(const type& m2) const { if (this == &m2) return true; else if (cptr()==m2.cptr() && size()==m2.size() && (isReal(T()) || sym() == m2.sym())) { if (uplo() == m2.uplo()) return (stepi() == m2.stepi() && stepj() == m2.stepj() && ct() == m2.ct()); else return (stepi() == m2.stepj() && stepj() == m2.stepi() && issym() == (ct()==m2.ct())); } else return false; } inline void assignToM(MatrixView m2) const { TMVAssert(isReal(T())); TMVAssert(m2.colsize() == size()); TMVAssert(m2.rowsize() == size()); assignToS(SymMatrixViewOf(m2,Upper)); if (size() > 0) m2.lowerTri().offDiag() = m2.upperTri().offDiag().transpose(); } inline void assignToM(MatrixView m2) const { TMVAssert(m2.colsize() == size()); TMVAssert(m2.rowsize() == size()); if (issym()) { assignToS(SymMatrixViewOf(m2,Upper)); if (size() > 0) m2.lowerTri().offDiag() = m2.upperTri().offDiag().transpose(); } else { m2.diag().imagPart().setZero(); assignToS(HermMatrixViewOf(m2,Upper)); if (size() > 0) m2.lowerTri().offDiag() = m2.upperTri().offDiag().adjoint(); } } inline void assignToS(SymMatrixView m2) const { TMVAssert(isReal(T())); TMVAssert(m2.size() == size()); if (!isSameAs(m2)) m2.upperTri() = upperTri(); } inline void assignToS(SymMatrixView m2) const { TMVAssert(m2.size() == size()); TMVAssert(isReal(T()) || m2.sym() == sym()); if (!isSameAs(m2)) m2.upperTri() = upperTri(); } // // subMatrix // bool hasSubMatrix( ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2, ptrdiff_t istep, ptrdiff_t jstep) const; inline const_rec_type subMatrix( ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2) const { TMVAssert(hasSubMatrix(i1,i2,j1,j2,1,1)); if ( (uplo()==Upper && i2-j1<=1) || (uplo()==Lower && j2-i1<=1) ) return const_rec_type( cptr()+i1*stepi()+j1*stepj(), i2-i1,j2-j1,stepi(),stepj(),ct()); else return const_rec_type( cptr()+i1*stepj()+j1*stepi(), i2-i1,j2-j1,stepj(),stepi(), issym()?ct():TMV_ConjOf(T,ct())); } inline const_rec_type subMatrix( ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2, ptrdiff_t istep, ptrdiff_t jstep) const { TMVAssert(hasSubMatrix(i1,i2,j1,j2,istep,jstep)); if ( (uplo()==Upper && i2-j1<=istep) || (uplo()==Lower && j2-i1<=istep) ) return const_rec_type( cptr()+i1*stepi()+j1*stepj(), (i2-i1)/istep,(j2-j1)/jstep,istep*stepi(),jstep*stepj(), ct()); else return const_rec_type( cptr()+i1*stepj()+j1*stepi(), (i2-i1)/istep,(j2-j1)/jstep,istep*stepj(),jstep*stepi(), issym()?ct():TMV_ConjOf(T,ct())); } bool hasSubVector( ptrdiff_t i, ptrdiff_t j, ptrdiff_t istep, ptrdiff_t jstep, ptrdiff_t n) const; inline const_vec_type subVector( ptrdiff_t i, ptrdiff_t j, ptrdiff_t istep, ptrdiff_t jstep, ptrdiff_t n) const { TMVAssert(hasSubVector(i,j,istep,jstep,n)); if ((i-j<=0 && uplo()==Upper) || (j-i<=0 && uplo()==Lower)) return const_vec_type( cptr()+i*stepi()+j*stepj(),n, istep*stepi()+jstep*stepj(),ct()); else return const_vec_type( cptr()+i*stepj()+j*stepi(),n,istep*stepj()+jstep*stepi(), issym()?ct():TMV_ConjOf(T,ct())); } bool hasSubSymMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t istep) const; inline const_view_type subSymMatrix(ptrdiff_t i1, ptrdiff_t i2) const { TMVAssert(hasSubSymMatrix(i1,i2,1)); return const_view_type( cptr()+i1*(stepi()+stepj()),i2-i1, stepi(),stepj(),sym(),uplo(),ct()); } inline const_view_type subSymMatrix( ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t istep) const { TMVAssert(hasSubSymMatrix(i1,i2,istep)); return const_view_type( cptr()+i1*(stepi()+stepj()), (i2-i1)/istep,istep*stepi(),istep*stepj(),sym(),uplo(),ct()); } inline const_uppertri_type upperTri(DiagType dt = NonUnitDiag) const { if (uplo() == Upper) return const_uppertri_type( cptr(),size(),stepi(),stepj(),dt,ct()); else return const_uppertri_type( cptr(),size(),stepj(),stepi(),dt, issym()?ct():TMV_ConjOf(T,ct())); } inline const_uppertri_type unitUpperTri() const { if (uplo() == Upper) return const_uppertri_type( cptr(),size(),stepi(),stepj(),UnitDiag,ct()); else return const_uppertri_type( cptr(),size(),stepj(),stepi(),UnitDiag, issym()?ct():TMV_ConjOf(T,ct())); } inline const_lowertri_type lowerTri(DiagType dt = NonUnitDiag) const { if (uplo() == Lower) return const_lowertri_type( cptr(),size(),stepi(),stepj(),dt,ct()); else return const_lowertri_type( cptr(),size(),stepj(),stepi(),dt, issym()?ct():TMV_ConjOf(T,ct())); } inline const_lowertri_type unitLowerTri() const { if (uplo() == Lower) return const_lowertri_type( cptr(),size(), stepi(),stepj(),UnitDiag,ct()); else return const_lowertri_type( cptr(),size(),stepj(),stepi(),UnitDiag, issym()?ct():TMV_ConjOf(T,ct())); } inline const_realpart_type realPart() const { return const_realpart_type( reinterpret_cast(cptr()),size(), isReal(T()) ? stepi() : 2*stepi(), isReal(T()) ? stepj() : 2*stepj(), Sym, uplo(), NonConj); } inline const_realpart_type imagPart() const { TMVAssert(isComplex(T())); TMVAssert(issym()); // The imaginary part of a Hermitian matrix is anti-symmetric return const_realpart_type( reinterpret_cast(cptr())+1, size(),2*stepi(),2*stepj(), Sym,uplo(),NonConj); } // // Views // inline const_view_type view() const { return const_view_type( cptr(),size(),stepi(),stepj(),sym(),uplo(),ct()); } inline const_view_type transpose() const { return const_view_type( cptr(),size(),stepj(),stepi(),sym(),TMV_UTransOf(uplo()),ct()); } inline const_view_type conjugate() const { return const_view_type( cptr(),size(),stepi(),stepj(),sym(),uplo(),TMV_ConjOf(T,ct())); } inline const_view_type adjoint() const { return const_view_type( cptr(),size(),stepj(),stepi(),sym(),TMV_UTransOf(uplo()), TMV_ConjOf(T,ct())); } inline nonconst_type nonConst() const { return SymMatrixView( const_cast(cptr()),size(),stepi(),stepj(),sym(),uplo(),ct() TMV_FIRSTLAST1( cptr(),row(colsize()-1,0,colsize()).end().getP())); } // // Functions of Matrix // T det() const; RT logDet(T* sign=0) const; bool isSingular() const; inline T trace() const { return diag().sumElements(); } T sumElements() const; RT sumAbsElements() const; RT sumAbs2Elements() const; inline RT norm() const { return normF(); } RT normF() const; RT normSq(const RT scale = RT(1)) const; RT norm1() const; inline RT normInf() const { return norm1(); } RT maxAbsElement() const; RT maxAbs2Element() const; RT doNorm2() const; inline RT norm2() const { if (this->divIsSet() && this->getDivType() == SV) return DivHelper::norm2(); else return doNorm2(); } RT doCondition() const; inline RT condition() const { if (this->divIsSet() && this->getDivType() == SV) return DivHelper::condition(); else return doCondition(); } template void doMakeInverse(SymMatrixView sinv) const; template inline void makeInverse(SymMatrixView minv) const { TMVAssert(minv.size() == size()); TMVAssert(isherm() == minv.isherm()); TMVAssert(issym() == minv.issym()); doMakeInverse(minv); } inline void makeInverse(MatrixView minv) const { DivHelper::makeInverse(minv); } template inline void makeInverse(MatrixView minv) const { DivHelper::makeInverse(minv); } template inline void makeInverse(Matrix& minv) const { DivHelper::makeInverse(minv); } template inline void makeInverse(SymMatrix& sinv) const { TMVAssert(issym()); makeInverse(sinv.view()); } template inline void makeInverse(HermMatrix& sinv) const { TMVAssert(isherm()); makeInverse(sinv.view()); } QuotXS QInverse() const; inline QuotXS inverse() const { return QInverse(); } // // Division Control // void setDiv() const; inline void divideUsing(DivType dt) const { TMVAssert(dt == CH || dt == LU || dt == SV); TMVAssert(isherm() || dt != CH); DivHelper::divideUsing(dt); } inline const SymLDLDiv& lud() const { divideUsing(LU); setDiv(); TMVAssert(this->getDiv()); TMVAssert(divIsLUDiv()); return static_cast&>(*this->getDiv()); } inline const HermCHDiv& chd() const { TMVAssert(isherm()); divideUsing(CH); setDiv(); TMVAssert(this->getDiv()); TMVAssert(divIsCHDiv()); return static_cast&>(*this->getDiv()); } inline const HermSVDiv& svd() const { TMVAssert(isherm()); divideUsing(SV); setDiv(); TMVAssert(this->getDiv()); TMVAssert(divIsHermSVDiv()); return static_cast&>(*this->getDiv()); } inline const SymSVDiv& symsvd() const { TMVAssert(isComplex(T())); TMVAssert(issym()); divideUsing(SV); setDiv(); TMVAssert(this->getDiv()); TMVAssert(divIsSymSVDiv()); return static_cast&>(*this->getDiv()); } // // I/O // void write(const TMV_Writer& writer) const; virtual const T* cptr() const = 0; virtual ptrdiff_t stepi() const = 0; virtual ptrdiff_t stepj() const = 0; virtual UpLoType uplo() const = 0; virtual ConjType ct() const = 0; virtual inline bool isrm() const { return stepj() == 1; } virtual inline bool iscm() const { return stepi() == 1; } inline bool isconj() const { TMVAssert(isComplex(T()) || ct()==NonConj); return isComplex(T()) && ct() == Conj; } inline bool isherm() const { return isReal(T()) || sym() == Herm; } inline bool issym() const { return isReal(T()) || sym() == Sym; } inline bool isupper() const { return uplo() == Upper; } inline bool isHermOK() const { if (issym()) return true; else return diag().imagPart().normInf() == RT(0); } virtual T cref(ptrdiff_t i, ptrdiff_t j) const; protected : inline const BaseMatrix& getMatrix() const { return *this; } private : type& operator=(const type&); bool divIsLUDiv() const; bool divIsCHDiv() const; bool divIsHermSVDiv() const; bool divIsSymSVDiv() const; }; // GenSymMatrix template class ConstSymMatrixView : public GenSymMatrix { public : typedef ConstSymMatrixView type; typedef GenSymMatrix base; inline ConstSymMatrixView(const type& rhs) : itsm(rhs.itsm), itss(rhs.itss), itssi(rhs.itssi), itssj(rhs.itssj), itssym(rhs.itssym), itsuplo(rhs.itsuplo), itsct(rhs.itsct) { TMVAssert(Attrib::viewok); } inline ConstSymMatrixView(const base& rhs) : itsm(rhs.cptr()), itss(rhs.size()), itssi(rhs.stepi()), itssj(rhs.stepj()), itssym(rhs.sym()), itsuplo(rhs.uplo()), itsct(rhs.ct()) { TMVAssert(Attrib::viewok); } inline ConstSymMatrixView( const T* _m, ptrdiff_t _s, ptrdiff_t _si, ptrdiff_t _sj, SymType _sym, UpLoType _uplo, ConjType _ct) : itsm(_m), itss(_s), itssi(_si), itssj(_sj), itssym(_sym), itsuplo(_uplo), itsct(_ct) { TMVAssert(Attrib::viewok); } virtual inline ~ConstSymMatrixView() { #ifdef TMV_EXTRA_DEBUG const_cast(itsm) = 0; #endif } inline ptrdiff_t size() const { return itss; } inline const T* cptr() const { return itsm; } inline ptrdiff_t stepi() const { return itssi; } inline ptrdiff_t stepj() const { return itssj; } inline SymType sym() const { return itssym; } inline UpLoType uplo() const { return itsuplo; } inline ConjType ct() const { return itsct; } protected : const T*const itsm; const ptrdiff_t itss; const ptrdiff_t itssi; const ptrdiff_t itssj; const SymType itssym; const UpLoType itsuplo; const ConjType itsct; private : type& operator=(const type&); }; // ConstSymMatrixView template class ConstSymMatrixView : public ConstSymMatrixView { public : typedef TMV_RealType(T) RT; typedef ConstSymMatrixView type; typedef ConstSymMatrixView c_type; typedef GenSymMatrix base; typedef ConstSymMatrixView const_view_type; typedef const_view_type const_transpose_type; typedef const_view_type const_conjugate_type; typedef const_view_type const_adjoint_type; typedef ConstVectorView const_vec_type; typedef ConstMatrixView const_rec_type; typedef ConstUpperTriMatrixView const_uppertri_type; typedef ConstLowerTriMatrixView const_lowertri_type; typedef ConstSymMatrixView const_realpart_type; typedef SymMatrixView nonconst_type; inline ConstSymMatrixView(const type& rhs) : c_type(rhs) {} inline ConstSymMatrixView(const c_type& rhs) : c_type(rhs) {} inline ConstSymMatrixView(const base& rhs) : c_type(rhs) {} inline ConstSymMatrixView( const T* _m, ptrdiff_t _s, ptrdiff_t _si, ptrdiff_t _sj, SymType _sym, UpLoType _uplo, ConjType _ct) : c_type(_m,_s,_si,_sj,_sym,_uplo,_ct) {} virtual inline ~ConstSymMatrixView() {} // // Access Functions // inline T operator()(ptrdiff_t i, ptrdiff_t j) const { TMVAssert(i>0 && i<=this->size()); TMVAssert(j>0 && j<=this->size()); return base::cref(i-1,j-1); } inline const_vec_type row(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2) const { TMVAssert(i>0 && i<=this->size()); TMVAssert(j1>0 && j1-j2<=0 && j2<=this->size()); return base::row(i-1,j1-1,j2); } inline const_vec_type col(ptrdiff_t j, ptrdiff_t i1, ptrdiff_t i2) const { TMVAssert(j>0 && j<=this->size()); TMVAssert(i1>0 && i1-i2<=0 && i2<=this->size()); return base::col(j-1,i1-1,i2); } inline const_vec_type diag() const { return base::diag(); } inline const_vec_type diag(ptrdiff_t i) const { return base::diag(i); } inline const_vec_type diag(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2) const { TMVAssert(j1>0); return base::diag(i,j1-1,j2); } // // SubMatrix // bool hasSubMatrix( ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2, ptrdiff_t istep, ptrdiff_t jstep) const; bool hasSubVector(ptrdiff_t i, ptrdiff_t j, ptrdiff_t istep, ptrdiff_t jstep, ptrdiff_t n) const; bool hasSubSymMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t istep) const; inline const_rec_type subMatrix( ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2) const { TMVAssert(hasSubMatrix(i1,i2,j1,j2,1,1)); return base::subMatrix(i1-1,i2,j1-1,j2); } inline const_rec_type subMatrix( ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2, ptrdiff_t istep, ptrdiff_t jstep) const { TMVAssert(hasSubMatrix(i1,i2,j1,j2,istep,jstep)); return base::subMatrix(i1-1,i2-1+istep,j1-1,j2-1+jstep, istep,jstep); } inline const_vec_type subVector( ptrdiff_t i, ptrdiff_t j, ptrdiff_t istep, ptrdiff_t jstep, ptrdiff_t n) const { TMVAssert(hasSubVector(i,j,istep,jstep,n)); return base::subVector(i-1,j-1,istep,jstep,n); } inline const_view_type subSymMatrix(ptrdiff_t i1, ptrdiff_t i2) const { TMVAssert(hasSubSymMatrix(i1,i2,1)); return base::subSymMatrix(i1-1,i2); } inline const_view_type subSymMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t istep) const { TMVAssert(hasSubSymMatrix(i1,i2,istep)); return base::subSymMatrix(i1-1,i2-1+istep,istep); } inline const_uppertri_type upperTri(DiagType dt = NonUnitDiag) const { return base::upperTri(dt); } inline const_uppertri_type unitUpperTri() const { return base::unitUpperTri(); } inline const_lowertri_type lowerTri(DiagType dt = NonUnitDiag) const { return base::lowerTri(dt); } inline const_lowertri_type unitLowerTri() const { return base::unitLowerTri(); } inline const_realpart_type realPart() const { return base::realPart(); } inline const_realpart_type imagPart() const { return base::imagPart(); } // // Views // inline const_view_type view() const { return base::view(); } inline const_view_type transpose() const { return base::transpose(); } inline const_view_type conjugate() const { return base::conjugate(); } inline const_view_type adjoint() const { return base::adjoint(); } inline nonconst_type nonConst() const { return base::nonConst(); } private : type& operator=(const type&); }; // FortranStyle ConstSymMatrixView template class SymMatrixView : public GenSymMatrix { public: typedef TMV_RealType(T) RT; typedef TMV_ComplexType(T) CT; typedef SymMatrixView type; typedef GenSymMatrix base; typedef SymMatrixView view_type; typedef view_type transpose_type; typedef view_type conjugate_type; typedef view_type adjoint_type; typedef VectorView vec_type; typedef MatrixView rec_type; typedef UpperTriMatrixView uppertri_type; typedef LowerTriMatrixView lowertri_type; typedef SymMatrixView realpart_type; typedef ConstSymMatrixView const_view_type; typedef const_view_type const_transpose_type; typedef const_view_type const_conjugate_type; typedef const_view_type const_adjoint_type; typedef ConstVectorView const_vec_type; typedef ConstMatrixView const_rec_type; typedef ConstUpperTriMatrixView const_uppertri_type; typedef ConstLowerTriMatrixView const_lowertri_type; typedef ConstSymMatrixView const_realpart_type; typedef typename RefHelper::reference reference; // // Constructors // inline SymMatrixView(const type& rhs) : itsm(rhs.itsm), itss(rhs.itss), itssi(rhs.itssi), itssj(rhs.itssj), itssym(rhs.sym()), itsuplo(rhs.uplo()), itsct(rhs.ct()) TMV_DEFFIRSTLAST(rhs._first,rhs._last) { TMVAssert(Attrib::viewok); } inline SymMatrixView( T* _m, ptrdiff_t _s, ptrdiff_t _si, ptrdiff_t _sj, SymType _sym, UpLoType _uplo, ConjType _ct TMV_PARAMFIRSTLAST(T) ) : itsm(_m), itss(_s), itssi(_si), itssj(_sj), itssym(_sym), itsuplo(_uplo), itsct(_ct) TMV_DEFFIRSTLAST(_first,_last) { TMVAssert(Attrib::viewok); } virtual inline ~SymMatrixView() { TMV_SETFIRSTLAST(0,0); #ifdef TMV_EXTRA_DEBUG const_cast(itsm) = 0; #endif } // // Op= // inline type& operator=(const type& m2) { TMVAssert(size() == m2.size()); TMVAssert(isReal(T()) || m2.sym() == sym()); if (!this->isSameAs(m2)) upperTri() = m2.upperTri(); return *this; } inline type& operator=(const GenSymMatrix& m2) { TMVAssert(size() == m2.size()); m2.assignToS(*this); return *this; } inline type& operator=(const GenSymMatrix& m2) { TMVAssert(isComplex(T())); TMVAssert(size() == m2.size()); TMVAssert(m2.sym() == sym()); m2.assignToS(*this); return *this; } template inline type& operator=(const GenSymMatrix& m2) { TMVAssert(size() == m2.size()); TMVAssert(isComplex(T()) || isReal(T2())); TMVAssert(isReal(T2()) || m2.sym() == sym()); if (!this->isSameAs(m2)) upperTri() = m2.upperTri(); return *this; } inline type& operator=(const T& x) { TMVAssert(issym() || TMV_IMAG(x) == RT(0)); return setToIdentity(x); } inline type& operator=(const AssignableToSymMatrix& m2) { TMVAssert(size() == m2.size()); m2.assignToS(view()); return *this; } inline type& operator=(const AssignableToSymMatrix& m2) { TMVAssert(isComplex(T())); TMVAssert(size() == m2.size()); TMVAssert(sym() == m2.sym()); m2.assignToS(view()); return *this; } inline type& operator=(const GenDiagMatrix& m2) { TMVAssert(size() == m2.size()); m2.assignToD(DiagMatrixViewOf(diag())); upperTri().offDiag().setZero(); return *this; } inline type& operator=(const GenDiagMatrix& m2) { TMVAssert(isComplex(T())); TMVAssert(size() == m2.size()); TMVAssert(issym()); m2.assignToD(DiagMatrixViewOf(diag())); upperTri().offDiag().setZero(); TMVAssert(this->isHermOK()); return *this; } template inline type& operator=(const OProdVV& opvv) { TMVAssert(size() == opvv.colsize()); TMVAssert(size() == opvv.rowsize()); TMVAssert(opvv.getV1().isSameAs( issym() ? opvv.getV2().view() : opvv.getV2().conjugate())); TMVAssert(issym() || TMV_IMAG(opvv.getX()) == RT(0)); Rank1Update(opvv.getX(),opvv.getV1(),*this); return *this; } template inline type& operator=(const OProdVV& opvv) { TMVAssert(isComplex(T())); TMVAssert(size() == opvv.colsize()); TMVAssert(size() == opvv.rowsize()); TMVAssert(opvv.getV1().isSameAs( issym() ? opvv.getV2().view() : opvv.getV2().conjugate())); TMVAssert(issym() || TMV_IMAG(opvv.getX()) == RT(0)); Rank1Update(opvv.getX(),opvv.getV1(),*this); return *this; } template inline type& operator=(const ProdMM& pmm) { TMVAssert(size() == pmm.colsize()); TMVAssert(size() == pmm.rowsize()); TMVAssert(pmm.getM1().isSameAs(issym() ? pmm.getM2().transpose() : pmm.getM2().adjoint())); TMVAssert(issym() || TMV_IMAG(pmm.getX()) == RT(0)); RankKUpdate(pmm.getX(),pmm.getM1(),*this); return *this; } template inline type& operator=(const ProdMM& pmm) { TMVAssert(isComplex(T())); TMVAssert(size() == pmm.colsize()); TMVAssert(size() == pmm.rowsize()); TMVAssert(pmm.getM1().isSameAs( issym() ? pmm.getM2().transpose() : pmm.getM2().adjoint())); TMVAssert(issym() || TMV_IMAG(pmm.getX()) == RT(0)); RankKUpdate(pmm.getX(),pmm.getM1(),*this); return *this; } template inline type& operator=(const ProdUL& pmm) { TMVAssert(size() == pmm.colsize()); TMVAssert(size() == pmm.rowsize()); TMVAssert(pmm.getM1().isSameAs( issym() ? pmm.getM2().transpose() : pmm.getM2().adjoint())); TMVAssert(issym() || TMV_IMAG(pmm.getX()) == RT(0)); RankKUpdate(pmm.getX(),pmm.getM1(),*this); return *this; } template inline type& operator=(const ProdUL& pmm) { TMVAssert(isComplex(T())); TMVAssert(size() == pmm.colsize()); TMVAssert(size() == pmm.rowsize()); TMVAssert(pmm.getM1().isSameAs( issym() ? pmm.getM2().transpose() : pmm.getM2().adjoint())); TMVAssert(issym() || TMV_IMAG(pmm.getX()) == RT(0)); RankKUpdate(pmm.getX(),pmm.getM1(),*this); return *this; } template inline type& operator=(const ProdLU& pmm) { TMVAssert(size() == pmm.colsize()); TMVAssert(size() == pmm.rowsize()); TMVAssert(pmm.getM1().isSameAs( issym() ? pmm.getM2().transpose() : pmm.getM2().adjoint())); TMVAssert(issym() || TMV_IMAG(pmm.getX()) == RT(0)); RankKUpdate(pmm.getX(),pmm.getM1(),*this); return *this; } template inline type& operator=(const ProdLU& pmm) { TMVAssert(isComplex(T())); TMVAssert(size() == pmm.colsize()); TMVAssert(size() == pmm.rowsize()); TMVAssert(pmm.getM1().isSameAs( issym() ? pmm.getM2().transpose() : pmm.getM2().adjoint())); TMVAssert(issym() || TMV_IMAG(pmm.getX()) == RT(0)); RankKUpdate(pmm.getX(),pmm.getM1(),*this); return *this; } // // Access // inline reference operator()(ptrdiff_t i,ptrdiff_t j) { TMVAssert(i>=0 && i=0 && j=0 && i=0 && j1-j2<=0 && j2<=size()); if ((i-j1<=0 && uplo()==Upper) || (j2-i<=1 && uplo()==Lower)) return vec_type( ptr()+i*stepi()+j1*stepj(),j2-j1,stepj(), ct() TMV_FIRSTLAST); else return vec_type( ptr()+i*stepj()+j1*stepi(),j2-j1,stepi(), this->issym()?ct():TMV_ConjOf(T,ct()) TMV_FIRSTLAST); } inline vec_type col(ptrdiff_t j, ptrdiff_t i1, ptrdiff_t i2) { TMVAssert(j>=0 && j=0 && i1-i2<=0 && i2<=size()); if ((i2-j<=1 && uplo()==Upper) || (j-i1<=0 && uplo()==Lower)) return vec_type( ptr()+i1*stepi()+j*stepj(),i2-i1,stepi(), ct() TMV_FIRSTLAST); else return vec_type( ptr()+i1*stepj()+j*stepi(),i2-i1,stepj(), this->issym()?ct():TMV_ConjOf(T,ct()) TMV_FIRSTLAST); } inline vec_type diag() { return vec_type(ptr(),size(),stepi()+stepj(),ct() TMV_FIRSTLAST); } inline vec_type diag(ptrdiff_t i) { TMVAssert(i>=-size() && i<=size()); if (i>=0) if (uplo()==Upper) return vec_type( ptr()+i*stepj(),size()-i, stepi()+stepj(),ct() TMV_FIRSTLAST); else return vec_type( ptr()+i*stepi(),size()-i, stepi()+stepj(),this->issym()?ct():TMV_ConjOf(T,ct()) TMV_FIRSTLAST); else if (uplo()==Upper) return vec_type( ptr()-i*stepj(),size()+i, stepi()+stepj(),this->issym()?ct():TMV_ConjOf(T,ct()) TMV_FIRSTLAST); else return vec_type( ptr()-i*stepi(),size()+i, stepi()+stepj(),ct() TMV_FIRSTLAST); } inline vec_type diag(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2) { TMVAssert(i>=-size() && i<=size()); TMVAssert(j1>=0 && j1-j2<=0 && j2<=size()-std::abs(i)); const ptrdiff_t ds = stepi()+stepj(); if (i>=0) if (uplo()==Upper) return vec_type( ptr()+i*stepj()+j1*ds,j2-j1,ds,ct() TMV_FIRSTLAST); else return vec_type( ptr()+i*stepi()+j1*ds,j2-j1,ds, this->issym()?ct():TMV_ConjOf(T,ct()) TMV_FIRSTLAST); else if (uplo()==Upper) return vec_type( ptr()-i*stepj()+j1*ds,j2-j1,ds, this->issym()?ct():TMV_ConjOf(T,ct()) TMV_FIRSTLAST); else return vec_type( ptr()-i*stepi()+j1*ds,j2-j1,ds,ct() TMV_FIRSTLAST); } inline T operator()(ptrdiff_t i,ptrdiff_t j) const { return base::operator()(i,j); } inline const_vec_type row(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2) const { return base::row(i,j1,j2); } inline const_vec_type col(ptrdiff_t j, ptrdiff_t i1, ptrdiff_t i2) const { return base::col(j,i1,i2); } inline const_vec_type diag() const { return base::diag(); } inline const_vec_type diag(ptrdiff_t i) const { return base::diag(i); } inline const_vec_type diag(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2) const { return base::diag(i,j1,j2); } // // Modifying Functions // inline type& setZero() { upperTri().setZero(); return *this; } inline type& setAllTo(const T& x) { TMVAssert(TMV_IMAG(x)==RT(0) || this->issym()); upperTri().setAllTo(x); return *this; } inline type& addToAll(const T& x) { TMVAssert(TMV_IMAG(x)==RT(0) || this->issym()); upperTri().addToAll(x); return *this; } inline type& clip(RT thresh) { upperTri().clip(thresh); return *this; } inline type& transposeSelf() { if (!this->issym()) upperTri().conjugateSelf(); return *this; } inline type& conjugateSelf() { if (isComplex(T())) upperTri().conjugateSelf(); return *this; } inline type& setToIdentity(const T& x=T(1)) { TMVAssert(TMV_IMAG(x)==RT(0) || this->issym()); setZero(); diag().setAllTo(x); return *this; } type& swapRowsCols(ptrdiff_t i1, ptrdiff_t i2); type& permuteRowsCols(const ptrdiff_t* p, ptrdiff_t i1, ptrdiff_t i2); type& reversePermuteRowsCols(const ptrdiff_t* p, ptrdiff_t i1, ptrdiff_t i2); inline type& permuteRowsCols(const ptrdiff_t* p) { return permuteRowsCols(p,0,size()); } inline type& reversePermuteRowsCols(const ptrdiff_t* p) { return reversePermuteRowsCols(p,0,size()); } // // subMatrix // inline rec_type subMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2) { TMVAssert(base::hasSubMatrix(i1,i2,j1,j2,1,1)); if ( (uplo()==Upper && i2-j1<=1) || (uplo()==Lower && j2-i1<=1) ) return rec_type( ptr()+i1*stepi()+j1*stepj(), i2-i1,j2-j1,stepi(),stepj(),ct() TMV_FIRSTLAST); else return rec_type( ptr()+i1*stepj()+j1*stepi(),i2-i1,j2-j1,stepj(),stepi(), this->issym()?ct():TMV_ConjOf(T,ct()) TMV_FIRSTLAST); } inline rec_type subMatrix( ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2, ptrdiff_t istep, ptrdiff_t jstep) { TMVAssert(base::hasSubMatrix(i1,i2,j1,j2,istep,jstep)); if ( (uplo()==Upper && i2-j1<=istep) || (uplo()==Lower && j2-i1<=istep) ) return rec_type( ptr()+i1*stepi()+j1*stepj(), (i2-i1)/istep,(j2-j1)/jstep,istep*stepi(),jstep*stepj(), ct() TMV_FIRSTLAST); else return rec_type( ptr()+i1*stepj()+j1*stepi(),(i2-i1)/istep,(j2-j1)/jstep, istep*stepj(),jstep*stepi(), this->issym()?ct():TMV_ConjOf(T,ct()) TMV_FIRSTLAST); } inline vec_type subVector(ptrdiff_t i, ptrdiff_t j, ptrdiff_t istep, ptrdiff_t jstep, ptrdiff_t n) { TMVAssert(base::hasSubVector(i,j,istep,jstep,n)); if ((i-j<=0 && uplo()==Upper) || (j-i<=0 && uplo()==Lower)) return vec_type( ptr()+i*stepi()+j*stepj(),n, istep*stepi()+jstep*stepj(),ct() TMV_FIRSTLAST); else return vec_type( ptr()+i*stepj()+j*stepi(),n,istep*stepj()+jstep*stepi(), this->issym()?ct():TMV_ConjOf(T,ct()) TMV_FIRSTLAST); } inline view_type subSymMatrix(ptrdiff_t i1, ptrdiff_t i2) { TMVAssert(base::hasSubSymMatrix(i1,i2,1)); return view_type( ptr()+i1*(stepi()+stepj()),i2-i1, stepi(),stepj(),sym(),uplo(),ct() TMV_FIRSTLAST); } inline view_type subSymMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t istep) { TMVAssert(base::hasSubSymMatrix(i1,i2,istep)); return view_type( ptr()+i1*(stepi()+stepj()),(i2-i1)/istep, istep*stepi(),istep*stepj(),sym(),uplo(), ct() TMV_FIRSTLAST); } inline uppertri_type upperTri(DiagType dt = NonUnitDiag) { if (uplo() == Upper) return uppertri_type( ptr(),size(),stepi(),stepj(),dt,ct() TMV_FIRSTLAST); else return uppertri_type( ptr(),size(),stepj(),stepi(),dt, this->issym()?ct():TMV_ConjOf(T,ct()) TMV_FIRSTLAST); } inline uppertri_type unitUpperTri() { if (uplo() == Upper) return uppertri_type( ptr(),size(),stepi(),stepj(),UnitDiag,ct() TMV_FIRSTLAST); else return uppertri_type( ptr(),size(),stepj(),stepi(),UnitDiag, this->issym()?ct():TMV_ConjOf(T,ct()) TMV_FIRSTLAST); } inline lowertri_type lowerTri(DiagType dt = NonUnitDiag) { if (uplo() == Lower) return lowertri_type( ptr(),size(),stepi(),stepj(),dt,ct() TMV_FIRSTLAST); else return lowertri_type( ptr(),size(),stepj(),stepi(),dt, this->issym()?ct():TMV_ConjOf(T,ct()) TMV_FIRSTLAST); } inline lowertri_type unitLowerTri() { if (uplo() == Lower) return lowertri_type( ptr(),size(),stepi(),stepj(),UnitDiag,ct() TMV_FIRSTLAST); else return lowertri_type( ptr(),size(),stepj(),stepi(),UnitDiag, this->issym()?ct():TMV_ConjOf(T,ct()) TMV_FIRSTLAST); } inline realpart_type realPart() { return realpart_type( reinterpret_cast(ptr()),size(), isReal(T()) ? stepi() : 2*stepi(), isReal(T()) ? stepj() : 2*stepj(), sym(),uplo(),NonConj #ifdef TMVFLDEBUG ,reinterpret_cast(_first) ,reinterpret_cast(_last) #endif ); } inline realpart_type imagPart() { TMVAssert(isComplex(T())); TMVAssert(this->issym()); return realpart_type( reinterpret_cast(ptr())+1, size(),2*stepi(),2*stepj(),sym(),uplo(),NonConj #ifdef TMVFLDEBUG ,reinterpret_cast(_first)+1 ,reinterpret_cast(_last)+1 #endif ); } inline view_type view() { return *this; } inline view_type transpose() { return view_type( ptr(),size(),stepj(),stepi(),sym(),TMV_UTransOf(uplo()),ct() TMV_FIRSTLAST); } inline view_type conjugate() { return view_type( ptr(),size(),stepi(),stepj(),sym(),uplo(),TMV_ConjOf(T,ct()) TMV_FIRSTLAST); } inline view_type adjoint() { return view_type( ptr(),size(),stepj(),stepi(),sym(),TMV_UTransOf(uplo()), TMV_ConjOf(T,ct()) TMV_FIRSTLAST); } inline const_rec_type subMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2) const { return base::subMatrix(i1,i2,j1,j2); } inline const_rec_type subMatrix( ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2, ptrdiff_t istep, ptrdiff_t jstep) const { return base::subMatrix(i1,i2,j1,j2,istep,jstep); } inline const_vec_type subVector( ptrdiff_t i, ptrdiff_t j, ptrdiff_t istep, ptrdiff_t jstep, ptrdiff_t n) const { return base::subVector(i,j,istep,jstep,n); } inline const_view_type subSymMatrix(ptrdiff_t i1, ptrdiff_t i2) const { return base::subSymMatrix(i1,i2); } inline const_view_type subSymMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t istep) const { return base::subSymMatrix(i1,i2,istep); } inline const_uppertri_type upperTri(DiagType dt = NonUnitDiag) const { return base::upperTri(dt); } inline const_uppertri_type unitUpperTri() const { return base::unitUpperTri(); } inline const_lowertri_type lowerTri(DiagType dt = NonUnitDiag) const { return base::lowerTri(dt); } inline const_lowertri_type unitLowerTri() const { return base::unitLowerTri(); } inline const_realpart_type realPart() const { return base::realPart(); } inline const_realpart_type imagPart() const { return base::imagPart(); } inline const_view_type view() const { return base::view(); } inline const_view_type transpose() const { return base::transpose(); } inline const_view_type conjugate() const { return base::conjugate(); } inline const_view_type adjoint() const { return base::adjoint(); } // // I/O // void read(const TMV_Reader& reader); inline ptrdiff_t size() const { return itss; } inline const T* cptr() const { return itsm; } inline T* ptr() { return itsm; } inline ptrdiff_t stepi() const { return itssi; } inline ptrdiff_t stepj() const { return itssj; } inline SymType sym() const { return itssym; } inline UpLoType uplo() const { return itsuplo; } inline ConjType ct() const { return itsct; } using base::issym; using base::isherm; reference ref(ptrdiff_t i, ptrdiff_t j); protected : T*const itsm; const ptrdiff_t itss; const ptrdiff_t itssi; const ptrdiff_t itssj; const SymType itssym; const UpLoType itsuplo; const ConjType itsct; #ifdef TMVFLDEBUG public: const T* _first; const T* _last; protected: #endif }; // SymMatrixView template class SymMatrixView : public SymMatrixView { public: typedef TMV_RealType(T) RT; typedef TMV_ComplexType(T) CT; typedef SymMatrixView type; typedef SymMatrixView c_type; typedef GenSymMatrix base; typedef SymMatrixView view_type; typedef view_type transpose_type; typedef view_type conjugate_type; typedef view_type adjoint_type; typedef VectorView vec_type; typedef MatrixView rec_type; typedef UpperTriMatrixView uppertri_type; typedef LowerTriMatrixView lowertri_type; typedef SymMatrixView realpart_type; typedef ConstSymMatrixView const_view_type; typedef const_view_type const_transpose_type; typedef const_view_type const_conjugate_type; typedef const_view_type const_adjoint_type; typedef ConstVectorView const_vec_type; typedef ConstMatrixView const_rec_type; typedef ConstUpperTriMatrixView const_uppertri_type; typedef ConstLowerTriMatrixView const_lowertri_type; typedef ConstSymMatrixView const_realpart_type; typedef ConstSymMatrixView const_type; typedef typename RefHelper::reference reference; // // Constructors // inline SymMatrixView(const type& rhs) : c_type(rhs) {} inline SymMatrixView(const c_type& rhs) : c_type(rhs) {} inline SymMatrixView( T* _m, ptrdiff_t _s, ptrdiff_t _si, ptrdiff_t _sj, SymType _sym, UpLoType _uplo, ConjType _ct TMV_PARAMFIRSTLAST(T) ) : c_type(_m,_s,_si,_sj,_sym,_uplo,_ct TMV_FIRSTLAST1(_first,_last) ) {} virtual inline ~SymMatrixView() {} // // Op= // inline type& operator=(const type& m2) { c_type::operator=(m2); return *this; } inline type& operator=(const c_type& m2) { c_type::operator=(m2); return *this; } inline type& operator=(const GenSymMatrix& m2) { c_type::operator=(m2); return *this; } inline type& operator=(const GenSymMatrix& m2) { c_type::operator=(m2); return *this; } template inline type& operator=(const GenSymMatrix& m2) { c_type::operator=(m2); return *this; } inline type& operator=(const T& x) { c_type::operator=(x); return *this; } inline type& operator=(const AssignableToSymMatrix& m2) { c_type::operator=(m2); return *this; } inline type& operator=(const AssignableToSymMatrix& m2) { c_type::operator=(m2); return *this; } inline type& operator=(const GenDiagMatrix& m2) { c_type::operator=(m2); return *this; } inline type& operator=(const GenDiagMatrix& m2) { c_type::operator=(m2); return *this; } template inline type& operator=(const OProdVV& opvv) { c_type::operator=(opvv); return *this; } template inline type& operator=(const ProdMM& pmm) { c_type::operator=(pmm); return *this; } template inline type& operator=(const ProdLU& pmm) { c_type::operator=(pmm); return *this; } template inline type& operator=(const ProdUL& pmm) { c_type::operator=(pmm); return *this; } // // Access // inline reference operator()(ptrdiff_t i,ptrdiff_t j) { TMVAssert(i>0 && i<=this->size()); TMVAssert(j>0 && j<=this->size()); return c_type::ref(i-1,j-1); } inline vec_type row(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2) { TMVAssert(i>0 && i<=this->size()); TMVAssert(j1>0 && j1-j2<=0 && j2<=this->size()); return c_type::row(i-1,j1-1,j2); } inline vec_type col(ptrdiff_t j, ptrdiff_t i1, ptrdiff_t i2) { TMVAssert(j>0 && j<=this->size()); TMVAssert(i1>0 && i1-i2<=0 && i2<=this->size()); return c_type::col(j-1,i1-1,i2); } inline vec_type diag() { return c_type::diag(); } inline vec_type diag(ptrdiff_t i) { return c_type::diag(i); } inline vec_type diag(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2) { TMVAssert(j1>0); return c_type::diag(i,j1-1,j2); } inline T operator()(ptrdiff_t i,ptrdiff_t j) const { TMVAssert(i>0 && i<=this->size()); TMVAssert(j>0 && j<=this->size()); return c_type::cref(i-1,j-1); } inline const_vec_type row(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2) const { TMVAssert(i>0 && i<=this->size()); TMVAssert(j1>0 && j1-j2<=0 && j2<=this->size()); return c_type::row(i-1,j1-1,j2); } inline const_vec_type col(ptrdiff_t j, ptrdiff_t i1, ptrdiff_t i2) const { TMVAssert(j>0 && j<=this->size()); TMVAssert(i1>0 && i1-i2<=0 && i2<=this->size()); return c_type::col(j-1,i1-1,i2); } inline const_vec_type diag() const { return c_type::diag(); } inline const_vec_type diag(ptrdiff_t i) const { return c_type::diag(i); } inline const_vec_type diag(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2) const { TMVAssert(j1>0); return c_type::diag(i,j1-1,j2); } // // Modifying Functions // inline type& setZero() { c_type::setZero(); return *this; } inline type& setAllTo(const T& x) { c_type::setAllTo(x); return *this; } inline type& addToAll(const T& x) { c_type::addToAll(x); return *this; } inline type& clip(RT thresh) { c_type::clip(thresh); return *this; } inline type& conjugateSelf() { c_type::conjugateSelf(); return *this; } inline type& transposeSelf() { c_type::transposeSelf(); return *this; } inline type& setToIdentity(const T& x=T(1)) { c_type::setToIdentity(x); return *this; } inline type& swapRowsCols(ptrdiff_t i1, ptrdiff_t i2) { TMVAssert(i1>0 && i1<=this->size()); TMVAssert(i2>0 && i2<=this->size()); c_type::swapRowsCols(i1-1,i2-1); return *this; } inline type& permuteRowsCols(const ptrdiff_t* p, ptrdiff_t i1, ptrdiff_t i2) { TMVAssert(i1>0 && i1-i2<=0 && i2<=this->size()); c_type::permuteRowsCols(p,i1-1,i2); return *this; } inline type& reversePermuteRowsCols(const ptrdiff_t* p, ptrdiff_t i1, ptrdiff_t i2) { TMVAssert(i1>0 && i1-i2<=0 && i2<=this->size()); c_type::reversePermuteRowsCols(p,i1-1,i2); return *this; } inline type& permuteRowsCols(const ptrdiff_t* p) { c_type::permuteRowsCols(p); return *this; } inline type& reversePermuteRowsCols(const ptrdiff_t* p) { c_type::reversePermuteRowsCols(p); return *this; } // // subMatrix // inline bool hasSubMatrix( ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2, ptrdiff_t istep, ptrdiff_t jstep) const { return const_type(*this).hasSubMatrix(i1,i2,j1,j2,istep,jstep); } inline bool hasSubVector( ptrdiff_t i, ptrdiff_t j, ptrdiff_t istep, ptrdiff_t jstep, ptrdiff_t n) const { return const_type(*this).hasSubVector(i,j,istep,jstep,n); } inline bool hasSubSymMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t istep) const { return const_type(*this).hasSubSymMatrix(i1,i2,istep); } inline rec_type subMatrix( ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2) const { TMVAssert(hasSubMatrix(i1,i2,j1,j2,1,1)); return c_type::subMatrix(i1-1,i2,j1-1,j2); } inline rec_type subMatrix( ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2, ptrdiff_t istep, ptrdiff_t jstep) { TMVAssert(hasSubMatrix(i1,i2,j1,j2,istep,jstep)); return c_type::subMatrix( i1-1,i2-1+istep,j1-1,j2-1+jstep,istep,jstep); } inline vec_type subVector(ptrdiff_t i, ptrdiff_t j, ptrdiff_t istep, ptrdiff_t jstep, ptrdiff_t n) { TMVAssert(hasSubVector(i,j,istep,jstep,n)); return c_type::subVector(i-1,j-1,istep,jstep,n); } inline view_type subSymMatrix(ptrdiff_t i1, ptrdiff_t i2) { TMVAssert(hasSubSymMatrix(i1,i2,1)); return c_type::subSymMatrix(i1-1,i2); } inline view_type subSymMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t istep) { TMVAssert(hasSubSymMatrix(i1,i2,istep)); return c_type::subSymMatrix(i1-1,i2-1+istep,istep); } inline uppertri_type upperTri(DiagType dt = NonUnitDiag) { return c_type::upperTri(dt); } inline uppertri_type unitUpperTri() { return c_type::unitUpperTri(); } inline lowertri_type lowerTri(DiagType dt = NonUnitDiag) { return c_type::lowerTri(dt); } inline lowertri_type unitLowerTri() { return c_type::unitLowerTri(); } inline realpart_type realPart() { return c_type::realPart(); } inline realpart_type imagPart() { return c_type::imagPart(); } inline view_type view() { return c_type::view(); } inline view_type transpose() { return c_type::transpose(); } inline view_type conjugate() { return c_type::conjugate(); } inline view_type adjoint() { return c_type::adjoint(); } inline const_rec_type subMatrix( ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2, ptrdiff_t istep, ptrdiff_t jstep) const { TMVAssert(hasSubMatrix(i1,i2,j1,j2,istep,jstep)); return c_type::subMatrix( i1-1,i2-1+istep,j1-1,j2-1+jstep,istep,jstep); } inline const_vec_type subVector( ptrdiff_t i, ptrdiff_t j, ptrdiff_t istep, ptrdiff_t jstep, ptrdiff_t n) const { TMVAssert(hasSubVector(i,j,istep,jstep,n)); return c_type::subVector(i-1,j-1,istep,jstep,n); } inline const_view_type subSymMatrix(ptrdiff_t i1, ptrdiff_t i2) const { TMVAssert(hasSubSymMatrix(i1,i2,1)); return c_type::subSymMatrix(i1-1,i2); } inline const_view_type subSymMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t istep) const { TMVAssert(hasSubSymMatrix(i1,i2,istep)); return c_type::subSymMatrix(i1-1,i2-1+istep,istep); } inline const_uppertri_type upperTri(DiagType dt = NonUnitDiag) const { return c_type::upperTri(dt); } inline const_uppertri_type unitUpperTri() const { return c_type::unitUpperTri(); } inline const_lowertri_type lowerTri(DiagType dt = NonUnitDiag) const { return c_type::lowerTri(dt); } inline const_lowertri_type unitLowerTri() const { return c_type::unitLowerTri(); } inline const_realpart_type realPart() const { return c_type::realPart(); } inline const_realpart_type imagPart() const { return c_type::imagPart(); } inline const_view_type view() const { return c_type::view(); } inline const_view_type transpose() const { return c_type::transpose(); } inline const_view_type conjugate() const { return c_type::conjugate(); } inline const_view_type adjoint() const { return c_type::adjoint(); } }; // FortranStyle SymMatrixView template class SymMatrix : public GenSymMatrix { public: enum { S = A & AllStorageType }; enum { U = A & Upper }; enum { I = A & FortranStyle }; typedef TMV_RealType(T) RT; typedef TMV_ComplexType(T) CT; typedef SymMatrix type; typedef type copy_type; typedef GenSymMatrix base; typedef ConstSymMatrixView const_view_type; typedef const_view_type const_transpose_type; typedef const_view_type const_conjugate_type; typedef const_view_type const_adjoint_type; typedef ConstVectorView const_vec_type; typedef ConstMatrixView const_rec_type; typedef ConstUpperTriMatrixView const_uppertri_type; typedef ConstLowerTriMatrixView const_lowertri_type; typedef ConstSymMatrixView const_realpart_type; typedef SymMatrixView view_type; typedef view_type transpose_type; typedef view_type conjugate_type; typedef view_type adjoint_type; typedef VectorView vec_type; typedef MatrixView rec_type; typedef UpperTriMatrixView uppertri_type; typedef LowerTriMatrixView lowertri_type; typedef SymMatrixView realpart_type; typedef T& reference; // // Constructors // #define NEW_SIZE(s) itslen((s)*(s)), itsm(itslen), itss(s) \ TMV_DEFFIRSTLAST(itsm.get(),itsm.get()+itslen) explicit inline SymMatrix(ptrdiff_t _size=0) : NEW_SIZE(_size) { TMVAssert(Attrib::symmatrixok); TMVAssert(_size >= 0); #ifdef TMV_EXTRA_DEBUG setAllTo(T(888)); #endif } inline SymMatrix(ptrdiff_t _size, const T& x) : NEW_SIZE(_size) { TMVAssert(Attrib::symmatrixok); TMVAssert(_size >= 0); setAllTo(x); } inline SymMatrix(const type& rhs) : NEW_SIZE(rhs.size()) { TMVAssert(Attrib::symmatrixok); std::copy(rhs.cptr(),rhs.cptr()+itslen,itsm.get()); } inline SymMatrix(const GenSymMatrix& rhs) : NEW_SIZE(rhs.size()) { TMVAssert(Attrib::symmatrixok); if (rhs.issym()) rhs.assignToS(view()); else { if (uplo() == Upper) upperTri() = rhs.upperTri(); else lowerTri() = rhs.lowerTri(); } } inline SymMatrix(const GenSymMatrix& rhs) : NEW_SIZE(rhs.size()) { TMVAssert(Attrib::symmatrixok); TMVAssert(isComplex(T())); if (rhs.issym()) rhs.assignToS(view()); else { if (uplo() == Upper) upperTri() = rhs.upperTri(); else lowerTri() = rhs.lowerTri(); } } template inline SymMatrix(const GenSymMatrix& rhs) : NEW_SIZE(rhs.size()) { TMVAssert(Attrib::symmatrixok); if (uplo() == Upper) upperTri() = rhs.upperTri(); else lowerTri() = rhs.lowerTri(); } template inline SymMatrix(const GenMatrix& rhs) : NEW_SIZE(rhs.rowsize()) { TMVAssert(Attrib::symmatrixok); TMVAssert(rhs.isSquare()); if (uplo() == Upper) upperTri() = rhs.upperTri(); else lowerTri() = rhs.lowerTri(); } inline SymMatrix(const AssignableToSymMatrix& m2) : NEW_SIZE(m2.size()) { TMVAssert(Attrib::symmatrixok); TMVAssert(m2.issym()); m2.assignToS(view()); } inline SymMatrix(const AssignableToSymMatrix& m2) : NEW_SIZE(m2.size()) { TMVAssert(Attrib::symmatrixok); TMVAssert(isComplex(T())); TMVAssert(m2.issym()); m2.assignToS(view()); } inline explicit SymMatrix(const GenDiagMatrix& m2) : NEW_SIZE(m2.size()) { TMVAssert(Attrib::symmatrixok); TMVAssert(size() == m2.size()); setZero(); m2.assignToD(DiagMatrixViewOf(diag())); } inline explicit SymMatrix(const GenDiagMatrix& m2) : NEW_SIZE(m2.size()) { TMVAssert(Attrib::symmatrixok); TMVAssert(isComplex(T())); TMVAssert(size() == m2.size()); setZero(); m2.assignToD(DiagMatrixViewOf(diag())); } template inline SymMatrix(const OProdVV& opvv) : NEW_SIZE(opvv.colsize()) { TMVAssert(Attrib::symmatrixok); TMVAssert(opvv.colsize() == opvv.rowsize()); TMVAssert(opvv.getV1().isSameAs(opvv.getV2().view())); Rank1Update(opvv.getX(),opvv.getV1(),view()); } template inline SymMatrix(const ProdMM& pmm) : NEW_SIZE(pmm.colsize()) { TMVAssert(Attrib::symmatrixok); TMVAssert(pmm.colsize() == pmm.rowsize()); TMVAssert(pmm.getM1().isSameAs(pmm.getM2().transpose())); RankKUpdate(pmm.getX(),pmm.getM1(),view()); } template inline SymMatrix(const ProdUL& pmm) : NEW_SIZE(pmm.colsize()) { TMVAssert(Attrib::symmatrixok); TMVAssert(pmm.colsize() == pmm.rowsize()); TMVAssert(pmm.getM1().isSameAs(pmm.getM2().transpose())); RankKUpdate(pmm.getX(),pmm.getM1(),view()); } template inline SymMatrix(const ProdLU& pmm) : NEW_SIZE(pmm.colsize()) { TMVAssert(Attrib::symmatrixok); TMVAssert(pmm.colsize() == pmm.rowsize()); TMVAssert(pmm.getM1().isSameAs(pmm.getM2().transpose())); RankKUpdate(pmm.getX(),pmm.getM1(),view()); } #undef NEW_SIZE virtual inline ~SymMatrix() { TMV_SETFIRSTLAST(0,0); #ifdef TMV_EXTRA_DEBUG setAllTo(T(999)); #endif } // // Op= // inline type& operator=(const type& m2) { TMVAssert(size() == m2.size()); if (&m2 != this) std::copy(m2.cptr(),m2.cptr()+itslen,itsm.get()); return *this; } inline type& operator=(const GenSymMatrix& m2) { TMVAssert(size() == m2.size()); TMVAssert(m2.issym()); m2.assignToS(view()); return *this; } inline type& operator=(const GenSymMatrix& m2) { TMVAssert(isComplex(T())); TMVAssert(size() == m2.size()); TMVAssert(m2.issym()); m2.assignToS(view()); return *this; } template inline type& operator=(const GenSymMatrix& m2) { TMVAssert(size() == m2.size()); TMVAssert(isReal(T2()) || m2.issym()); upperTri() = m2.upperTri(); return *this; } inline type& operator=(const T& x) { return setToIdentity(x); } inline type& operator=(const AssignableToSymMatrix& m2) { TMVAssert(size() == m2.size()); TMVAssert(m2.issym()); m2.assignToS(view()); return *this; } inline type& operator=(const AssignableToSymMatrix& m2) { TMVAssert(isComplex(T())); TMVAssert(size() == m2.size()); TMVAssert(m2.issym()); m2.assignToS(view()); return *this; } inline type& operator=(const GenDiagMatrix& m2) { TMVAssert(size() == m2.size()); view() = m2; return *this; } inline type& operator=(const GenDiagMatrix& m2) { TMVAssert(isComplex(T())); TMVAssert(size() == m2.size()); view() = m2; return *this; } template inline type& operator=(const OProdVV& opvv) { TMVAssert(size() == opvv.colsize()); TMVAssert(size() == opvv.rowsize()); TMVAssert(opvv.getV1().isSameAs(opvv.getV2().view())); Rank1Update(opvv.getX(),opvv.getV1(),view()); return *this; } template inline type& operator=(const ProdMM& pmm) { TMVAssert(size() == pmm.colsize()); TMVAssert(size() == pmm.rowsize()); TMVAssert(pmm.getM1().isSameAs(pmm.getM2().transpose())); RankKUpdate(pmm.getX(),pmm.getM1(),view()); return *this; } template inline type& operator=(const ProdUL& pmm) { TMVAssert(size() == pmm.colsize()); TMVAssert(size() == pmm.rowsize()); TMVAssert(pmm.getM1().isSameAs(pmm.getM2().transpose())); RankKUpdate(pmm.getX(),pmm.getM1(),view()); return *this; } template inline type& operator=(const ProdLU& pmm) { TMVAssert(size() == pmm.colsize()); TMVAssert(size() == pmm.rowsize()); TMVAssert(pmm.getM1().isSameAs(pmm.getM2().transpose())); RankKUpdate(pmm.getX(),pmm.getM1(),view()); return *this; } // // Access // inline T operator()(ptrdiff_t i, ptrdiff_t j) const { if (I==int(CStyle)) { TMVAssert(i>=0 && i=0 && j0 && i<=size()); TMVAssert(j>0 && j<=size()); return cref(i-1,j-1); } } inline T& operator()(ptrdiff_t i, ptrdiff_t j) { if (I==int(CStyle)) { TMVAssert(i>=0 && i=0 && j0 && i<=size()); TMVAssert(j>0 && j<=size()); return ref(i-1,j-1); } } inline const_vec_type row(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2) const { if (I==int(FortranStyle)) { TMVAssert(i>0 && i<=size()); --i; TMVAssert(j1>0 && j1-j2<=0 && j2<=size()); --j1; } else { TMVAssert(i>=0 && i=0 && j1-j2<=0 && j2<=size()); } if ((uplo()==Upper && i-j1<=0) || (uplo()==Lower && j2-i<=1)) return const_vec_type( itsm.get()+i*stepi()+j1*stepj(), j2-j1,stepj(),NonConj); else return const_vec_type( itsm.get()+i*stepj()+j1*stepi(), j2-j1,stepi(),NonConj); } inline const_vec_type col(ptrdiff_t j, ptrdiff_t i1, ptrdiff_t i2) const { if (I==int(FortranStyle)) { TMVAssert(j>0 && j<=size()); --j; TMVAssert(i1>0 && i1-i2<=0 && i2<=size()); --i1; } else { TMVAssert(j>=0 && j=0 && i1-i2<=0 && i2<=size()); } if ((uplo()==Upper && i2-j<=1) || (uplo()==Lower && j-i1<=0)) return const_vec_type( itsm.get()+i1*stepi()+j*stepj(), i2-i1,stepi(),NonConj); else return const_vec_type( itsm.get()+i1*stepj()+j*stepi(), i2-i1,stepj(),NonConj); } inline const_vec_type diag() const { return const_vec_type( itsm.get(),size(),stepi()+stepj(),NonConj); } inline const_vec_type diag(ptrdiff_t i) const { TMVAssert(i>=-size() && i<=size()); i = std::abs(i); return const_vec_type( itsm.get()+i*(uplo()==Upper?stepj():stepi()), size()-i,stepi()+stepj(),NonConj); } inline const_vec_type diag(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2) const { TMVAssert(i>=-size() && i<=size()); if (I==int(FortranStyle)) { TMVAssert(j1>0 && j1-j2<=0 && j2<=size()-std::abs(i)); --j1; } else { TMVAssert(j1>=0 && j1-j2<=0 && j2<=size()-std::abs(i)); } i = std::abs(i); const ptrdiff_t ds = stepi()+stepj(); return const_vec_type( itsm.get()+i*(uplo()==Upper?stepj():stepi())+j1*ds, j2-j1,ds,NonConj); } inline vec_type row(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2) { if (I==int(FortranStyle)) { TMVAssert(i>0 && i<=size()); --i; TMVAssert(j1>0 && j1-j2<=0 && j2<=size()); --j1; } else { TMVAssert(i>=0 && i=0 && j1-j2<=0 && j2<=size()); } if ((uplo()==Upper && i-j1<=0) || (uplo()==Lower && j2-i<=1)) return vec_type( itsm.get()+i*stepi()+j1*stepj(), j2-j1,stepj(),NonConj TMV_FIRSTLAST); else return vec_type( itsm.get()+i*stepj()+j1*stepi(), j2-j1,stepi(),NonConj TMV_FIRSTLAST); } inline vec_type col(ptrdiff_t j, ptrdiff_t i1, ptrdiff_t i2) { if (I==int(FortranStyle)) { TMVAssert(j>0 && j<=size()); --j; TMVAssert(i1>0 && i1-i2<=0 && i2<=size()); --i1; } else { TMVAssert(j>=0 && j=0 && i1-i2<=0 && i2<=size()); } if ((uplo()==Upper && i2-j<=1) || (uplo()==Lower && j-i1<=0)) return vec_type( itsm.get()+i1*stepi()+j*stepj(), i2-i1,stepi(),NonConj TMV_FIRSTLAST); else return vec_type( itsm.get()+i1*stepj()+j*stepi(), i2-i1,stepj(),NonConj TMV_FIRSTLAST); } inline vec_type diag() { return vec_type( itsm.get(),size(),stepi()+stepj(),NonConj TMV_FIRSTLAST); } inline vec_type diag(ptrdiff_t i) { TMVAssert(i>=-size() && i<=size()); i = std::abs(i); TMVAssert(i<=size()); return vec_type( itsm.get()+i*(uplo()==Upper?stepj():stepi()), size()-i,stepi()+stepj(),NonConj TMV_FIRSTLAST); } inline vec_type diag(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2) { TMVAssert(i>=-size() && i<=size()); if (I==int(FortranStyle)) { TMVAssert(j1>0 && j1-j2<=0 && j2<=size()-std::abs(i)); --j1; } else { TMVAssert(j1>=0 && j1-j2<=0 && j2<=size()-std::abs(i)); } i = std::abs(i); const ptrdiff_t ds = stepi()+stepj(); return vec_type( itsm.get()+i*(uplo()==Upper?stepj():stepi())+j1*ds, j2-j1,ds,NonConj TMV_FIRSTLAST); } // // Modifying Functions // inline type& setZero() { std::fill_n(itsm.get(),itslen,T(0)); return *this; } inline type& setAllTo(const T& x) { upperTri().setAllTo(x); return *this; } inline type& addToAll(const T& x) { upperTri().addToAll(x); return *this; } inline type& clip(RT thresh) { upperTri().clip(thresh); return *this; } inline type& conjugateSelf() { if (isComplex(T())) upperTri().conjugateSelf(); return *this; } inline type& transposeSelf() { return *this; } inline type& setToIdentity(const T& x=T(1)) { setZero(); diag().setAllTo(x); return *this; } inline type& swapRowsCols(ptrdiff_t i1, ptrdiff_t i2) { view().swapRowsCols(i1,i2); return *this; } inline type& permuteRowsCols(const ptrdiff_t* p, ptrdiff_t i1, ptrdiff_t i2) { view().permuteRowsCols(p,i1,i2); return *this; } inline type& reversePermuteRowsCols(const ptrdiff_t* p, ptrdiff_t i1, ptrdiff_t i2) { view().reversePermuteRowsCols(p,i1,i2); return *this; } inline type& permuteRowsCols(const ptrdiff_t* p) { view().permuteRowsCols(p); return *this; } inline type& reversePermuteRowsCols(const ptrdiff_t* p) { view().reversePermuteRowsCols(p); return *this; } // // subMatrix // inline const_rec_type subMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2) const { TMVAssert(view().hasSubMatrix(i1,i2,j1,j2,1,1)); if (I==int(FortranStyle)) { --i1; --j1; } if ( (uplo()==Upper && i2-j1<=1) || (uplo()==Lower && j2-i1<=1) ) return const_rec_type( itsm.get()+i1*stepi()+j1*stepj(), i2-i1,j2-j1,stepi(),stepj(),NonConj); else return const_rec_type( itsm.get()+i1*stepj()+j1*stepi(), i2-i1,j2-j1,stepj(),stepi(),NonConj); } inline const_rec_type subMatrix( ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2, ptrdiff_t istep, ptrdiff_t jstep) const { TMVAssert(view().hasSubMatrix(i1,i2,j1,j2,istep,jstep)); if (I==int(FortranStyle)) { --i1; --j1; i2+=istep-1; j2+=jstep-1; } if ( (uplo()==Upper && i2-j1<=istep) || (uplo()==Lower && j2-i1<=jstep) ) return const_rec_type( itsm.get()+i1*stepi()+j1*stepj(), (i2-i1)/istep,(j2-j1)/jstep,istep*stepi(),jstep*stepj(), NonConj); else return const_rec_type( itsm.get()+i1*stepj()+j1*stepi(), (i2-i1)/istep,(j2-j1)/jstep,istep*stepj(),jstep*stepi(), NonConj); } inline const_vec_type subVector( ptrdiff_t i, ptrdiff_t j, ptrdiff_t istep, ptrdiff_t jstep, ptrdiff_t n) const { TMVAssert(view().hasSubVector(i,j,istep,jstep,n)); if (I==int(FortranStyle)) { --i; --j; } if ((uplo()==Upper && i-j<=0) || (uplo()==Lower && j-i<=0)) return const_vec_type( itsm.get()+i*stepi()+j*stepj(),n, istep*stepi()+jstep*stepj(),NonConj); else return const_vec_type( itsm.get()+i*stepj()+j*stepi(),n, istep*stepj()+jstep*stepi(),NonConj); } inline const_view_type subSymMatrix(ptrdiff_t i1, ptrdiff_t i2) const { TMVAssert(view().hasSubSymMatrix(i1,i2,1)); if (I==int(FortranStyle)) { --i1; } return const_view_type( itsm.get()+i1*(stepi()+stepj()),i2-i1, stepi(),stepj(),Sym,uplo(),NonConj); } inline const_view_type subSymMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t istep) const { TMVAssert(view().hasSubSymMatrix(i1,i2,istep)); if (I==int(FortranStyle)) { --i1; i2+=istep-1; } return const_view_type( itsm.get()+i1*(stepi()+stepj()), (i2-i1)/istep,istep*stepi(),istep*stepj(),Sym,uplo(), NonConj); } inline const_uppertri_type upperTri(DiagType dt = NonUnitDiag) const { return uplo()==Upper ? const_uppertri_type( itsm.get(),size(),stepi(),stepj(),dt,NonConj) : const_uppertri_type( itsm.get(),size(),stepj(),stepi(),dt,NonConj); } inline const_uppertri_type unitUpperTri() const { return uplo()==Upper ? const_uppertri_type( itsm.get(),size(),stepi(),stepj(),UnitDiag,NonConj) : const_uppertri_type( itsm.get(),size(),stepj(),stepi(),UnitDiag,NonConj); } inline const_lowertri_type lowerTri(DiagType dt = NonUnitDiag) const { return uplo()==Lower ? const_lowertri_type( itsm.get(),size(),stepi(),stepj(),dt,NonConj) : const_lowertri_type( itsm.get(),size(),stepj(),stepi(),dt,NonConj); } inline const_lowertri_type unitLowerTri() const { return uplo()==Lower ? const_lowertri_type( itsm.get(),size(), stepi(),stepj(),UnitDiag,NonConj) : const_lowertri_type( itsm.get(),size(),stepj(),stepi(),UnitDiag,NonConj); } inline const_realpart_type realPart() const { return const_realpart_type( reinterpret_cast(itsm.get()),size(), isReal(T()) ? stepi() : 2*stepi(), isReal(T()) ? stepj() : 2*stepj(), Sym,uplo(),NonConj); } inline const_realpart_type imagPart() const { TMVAssert(isComplex(T())); return const_realpart_type( reinterpret_cast(itsm.get())+1,size(), 2*stepi(),2*stepj(),Sym,uplo(),NonConj); } inline const_view_type view() const { return const_view_type( itsm.get(),size(),stepi(),stepj(),Sym,uplo(),NonConj); } inline const_view_type transpose() const { return const_view_type( itsm.get(),size(),stepj(),stepi(),Sym,TMV_UTransOf(U),NonConj); } inline const_view_type conjugate() const { return const_view_type( itsm.get(),size(),stepi(),stepj(),Sym,uplo(), TMV_ConjOf(T,NonConj)); } inline const_view_type adjoint() const { return const_view_type( itsm.get(),size(),stepj(),stepi(), Sym,TMV_UTransOf(U),TMV_ConjOf(T,NonConj)); } inline rec_type subMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2) { TMVAssert(view().hasSubMatrix(i1,i2,j1,j2,1,1)); if (I==int(FortranStyle)) { --i1; --j1; } if ( (uplo()==Upper && i2-j1<=1) || (uplo()==Lower && j2-i1<=1) ) return rec_type( itsm.get()+i1*stepi()+j1*stepj(), i2-i1,j2-j1,stepi(),stepj(),NonConj TMV_FIRSTLAST); else return rec_type( itsm.get()+i1*stepj()+j1*stepi(), i2-i1,j2-j1,stepj(),stepi(),NonConj TMV_FIRSTLAST); } inline rec_type subMatrix( ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2, ptrdiff_t istep, ptrdiff_t jstep) { TMVAssert(view().hasSubMatrix(i1,i2,j1,j2,istep,jstep)); if (I==int(FortranStyle)) { --i1; --j1; i2+=istep-1; j2+=jstep-1; } if ( (uplo()==Upper && i2-j1<=istep) || (uplo()==Lower && j2-i1<=jstep) ) return rec_type( itsm.get()+i1*stepi()+j1*stepj(), (i2-i1)/istep,(j2-j1)/jstep,istep*stepi(),jstep*stepj(), NonConj TMV_FIRSTLAST); else return rec_type( itsm.get()+i1*stepj()+j1*stepi(), (i2-i1)/istep,(j2-j1)/jstep,istep*stepj(),jstep*stepi(), NonConj TMV_FIRSTLAST); } inline vec_type subVector( ptrdiff_t i, ptrdiff_t j, ptrdiff_t istep, ptrdiff_t jstep, ptrdiff_t n) { TMVAssert(view().hasSubVector(i,j,istep,jstep,n)); if (I==int(FortranStyle)) { --i; --j; } if ((uplo()==Upper && i-j<=0) || (uplo()==Lower && j-i<=0)) return vec_type( itsm.get()+i*stepi()+j*stepj(),n, istep*stepi()+jstep*stepj(),NonConj TMV_FIRSTLAST); else return vec_type( itsm.get()+i*stepj()+j*stepi(),n, istep*stepj()+jstep*stepi(),NonConj TMV_FIRSTLAST); } inline view_type subSymMatrix(ptrdiff_t i1, ptrdiff_t i2) { TMVAssert(view().hasSubSymMatrix(i1,i2,1)); if (I==int(FortranStyle)) { --i1; } return view_type( itsm.get()+i1*(stepi()+stepj()),i2-i1, stepi(),stepj(),Sym,uplo(),NonConj TMV_FIRSTLAST); } inline view_type subSymMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t istep) { TMVAssert(view().hasSubSymMatrix(i1,i2,istep)); if (I==int(FortranStyle)) { --i1; i2+=istep-1; } return view_type( itsm.get()+i1*(stepi()+stepj()),(i2-i1)/istep, istep*stepi(),istep*stepj(),Sym,uplo(), NonConj TMV_FIRSTLAST); } inline uppertri_type upperTri(DiagType dt = NonUnitDiag) { return uplo()==Upper ? uppertri_type( itsm.get(),size(),stepi(),stepj(),dt,NonConj TMV_FIRSTLAST) : uppertri_type( itsm.get(),size(),stepj(),stepi(),dt,NonConj TMV_FIRSTLAST); } inline uppertri_type unitUpperTri() { return uplo()==Upper ? uppertri_type( itsm.get(),size(),stepi(),stepj(),UnitDiag,NonConj TMV_FIRSTLAST) : uppertri_type( itsm.get(),size(),stepj(),stepi(),UnitDiag,NonConj TMV_FIRSTLAST); } inline lowertri_type lowerTri(DiagType dt = NonUnitDiag) { return uplo()==Lower ? lowertri_type( itsm.get(),size(),stepi(),stepj(),dt,NonConj TMV_FIRSTLAST) : lowertri_type( itsm.get(),size(),stepj(),stepi(),dt,NonConj TMV_FIRSTLAST); } inline lowertri_type unitLowerTri() { return uplo()==Lower ? lowertri_type( itsm.get(),size(),stepi(),stepj(),UnitDiag,NonConj TMV_FIRSTLAST) : lowertri_type( itsm.get(),size(),stepj(),stepi(),UnitDiag,NonConj TMV_FIRSTLAST); } inline realpart_type realPart() { return realpart_type( reinterpret_cast(itsm.get()),size(), isReal(T()) ? stepi() : 2*stepi(), isReal(T()) ? stepj() : 2*stepj(), Sym,uplo(),NonConj #ifdef TMVFLDEBUG ,reinterpret_cast(_first) ,reinterpret_cast(_last) #endif ); } inline realpart_type imagPart() { TMVAssert(isComplex(T())); return realpart_type( reinterpret_cast(itsm.get())+1,size(), 2*stepi(),2*stepj(),Sym,uplo(),NonConj #ifdef TMVFLDEBUG ,reinterpret_cast(_first)+1 ,reinterpret_cast(_last)+1 #endif ); } inline view_type view() { return view_type( itsm.get(),size(),stepi(),stepj(),Sym,uplo(),NonConj TMV_FIRSTLAST); } inline view_type transpose() { return view_type( itsm.get(),size(),stepj(),stepi(), Sym,TMV_UTransOf(U),NonConj TMV_FIRSTLAST); } inline view_type conjugate() { return view_type( itsm.get(),size(),stepi(),stepj(), Sym,uplo(),TMV_ConjOf(T,NonConj) TMV_FIRSTLAST); } inline view_type adjoint() { return view_type( itsm.get(),size(),stepj(),stepi(), Sym,TMV_UTransOf(U),TMV_ConjOf(T,NonConj) TMV_FIRSTLAST); } // // I/O // void read(const TMV_Reader& reader); inline ptrdiff_t size() const { return itss; } inline const T* cptr() const { return itsm.get(); } inline T* ptr() { return itsm.get(); } inline ptrdiff_t stepi() const { return S==int(RowMajor) ? itss : 1; } inline ptrdiff_t stepj() const { return S==int(RowMajor) ? 1 : itss; } inline SymType sym() const { return Sym; } inline UpLoType uplo() const { return static_cast(U); } inline ConjType ct() const { return NonConj; } inline bool isrm() const { return S==int(RowMajor); } inline bool iscm() const { return S==int(ColMajor); } inline bool isconj() const { return false; } inline bool isherm() const { return isReal(T()); } inline bool issym() const { return true; } inline bool isupper() const { return U==int(Upper); } inline T& ref(ptrdiff_t i, ptrdiff_t j) { if ((uplo()==Upper && i <= j) || (uplo()==Lower && i>=j)) return itsm.get()[i*stepi() + j*stepj()]; else return itsm.get()[j*stepi() + i*stepj()]; } inline T cref(ptrdiff_t i, ptrdiff_t j) const { if ((uplo()==Upper && i <= j) || (uplo()==Lower && i>=j)) return itsm.get()[i*stepi() + j*stepj()]; else return itsm.get()[j*stepi() + i*stepj()]; } inline void resize(ptrdiff_t s) { TMVAssert(s >= 0); itslen = s*s; itsm.resize(itslen); itss = s; DivHelper::resetDivType(); #ifdef TMVFLDEBUG _first = itsm.get(); _last = _first+itslen; #endif #ifdef TMV_EXTRA_DEBUG setAllTo(T(888)); #endif } protected : ptrdiff_t itslen; AlignedArray itsm; ptrdiff_t itss; #ifdef TMVFLDEBUG public: const T* _first; const T* _last; #endif friend void Swap(SymMatrix& m1, SymMatrix& m2) { TMVAssert(m1.size() == m2.size()); m1.itsm.swapWith(m2.itsm); #ifdef TMVFLDEBUG TMV_SWAP(m1._first,m2._first); TMV_SWAP(m1._last,m2._last); #endif } }; // SymMatrix template class HermMatrix : public GenSymMatrix { public: enum { S = A & AllStorageType }; enum { U = A & Upper }; enum { I = A & FortranStyle }; typedef TMV_RealType(T) RT; typedef TMV_ComplexType(T) CT; typedef HermMatrix type; typedef type copy_type; typedef GenSymMatrix base; typedef ConstSymMatrixView const_view_type; typedef const_view_type const_transpose_type; typedef const_view_type const_conjugate_type; typedef const_view_type const_adjoint_type; typedef ConstVectorView const_vec_type; typedef ConstMatrixView const_rec_type; typedef ConstUpperTriMatrixView const_uppertri_type; typedef ConstLowerTriMatrixView const_lowertri_type; typedef ConstSymMatrixView const_realpart_type; typedef SymMatrixView view_type; typedef view_type transpose_type; typedef view_type conjugate_type; typedef view_type adjoint_type; typedef VectorView vec_type; typedef MatrixView rec_type; typedef UpperTriMatrixView uppertri_type; typedef LowerTriMatrixView lowertri_type; typedef SymMatrixView realpart_type; typedef typename RefHelper::reference reference; // // Constructors // #define NEW_SIZE(s) itslen((s)*(s)), itsm(itslen), itss(s) \ TMV_DEFFIRSTLAST(itsm.get(),itsm.get()+itslen) explicit inline HermMatrix(ptrdiff_t _size=0) : NEW_SIZE(_size) { TMVAssert(Attrib::symmatrixok); TMVAssert(_size >= 0); #ifdef TMV_EXTRA_DEBUG setAllTo(T(888)); #else if (isComplex(T())) diag().imagPart().setZero(); #endif } HermMatrix(ptrdiff_t _size, const RT& x) : NEW_SIZE(_size) { TMVAssert(Attrib::symmatrixok); TMVAssert(_size >= 0); setAllTo(x); } HermMatrix(const type& rhs) : NEW_SIZE(rhs.size()) { TMVAssert(Attrib::symmatrixok); std::copy(rhs.cptr(),rhs.cptr()+itslen,itsm.get()); } HermMatrix(const GenSymMatrix& rhs) : NEW_SIZE(rhs.size()) { TMVAssert(Attrib::symmatrixok); if (rhs.isherm()) rhs.assignToS(view()); else if (uplo() == Upper) upperTri() = rhs.upperTri(); else lowerTri() = rhs.lowerTri(); } HermMatrix(const GenSymMatrix& rhs) : NEW_SIZE(rhs.size()) { TMVAssert(Attrib::symmatrixok); TMVAssert(isComplex(T())); if (rhs.isherm()) rhs.assignToS(view()); else { if (uplo() == Upper) upperTri() = rhs.upperTri(); else lowerTri() = rhs.lowerTri(); diag().imagPart().setZero(); } } template inline HermMatrix(const GenSymMatrix& rhs) : NEW_SIZE(rhs.size()) { TMVAssert(Attrib::symmatrixok); if (uplo() == Upper) upperTri() = rhs.upperTri(); else lowerTri() = rhs.lowerTri(); if (isComplex(T()) && isComplex(T2()) && rhs.issym()) diag().imagPart().setZero(); } template inline HermMatrix(const GenMatrix& rhs) : NEW_SIZE(rhs.rowsize()) { TMVAssert(Attrib::symmatrixok); TMVAssert(rhs.isSquare()); if (uplo() == Upper) upperTri() = rhs.upperTri(); else lowerTri() = rhs.lowerTri(); if (isComplex(T()) && isComplex(T2())) diag().imagPart().setZero(); } inline HermMatrix(const AssignableToSymMatrix& m2) : NEW_SIZE(m2.size()) { TMVAssert(Attrib::symmatrixok); TMVAssert(m2.isherm()); m2.assignToS(view()); } inline HermMatrix(const AssignableToSymMatrix& m2) : NEW_SIZE(m2.size()) { TMVAssert(Attrib::symmatrixok); TMVAssert(isComplex(T())); TMVAssert(m2.isherm()); m2.assignToS(view()); } inline explicit HermMatrix(const GenDiagMatrix& m2) : NEW_SIZE(m2.size()) { TMVAssert(Attrib::symmatrixok); m2.assignToD(DiagMatrixViewOf(diag())); upperTri().offDiag().setZero(); } inline explicit HermMatrix(const GenDiagMatrix& m2) : NEW_SIZE(m2.size()) { TMVAssert(Attrib::symmatrixok); m2.assignToD(DiagMatrixViewOf(diag().realPart())); upperTri().offDiag().setZero(); if (isComplex(T())) diag().imagPart().setZero(); } template inline HermMatrix(const OProdVV& opvv) : NEW_SIZE(opvv.colsize()) { TMVAssert(Attrib::symmatrixok); TMVAssert(opvv.colsize() == opvv.rowsize()); TMVAssert(opvv.getV1().isSameAs(opvv.getV2().conjugate())); TMVAssert(TMV_IMAG(opvv.getX()) == RT(0)); Rank1Update(opvv.getX(),opvv.getV1(),view()); } template inline HermMatrix(const ProdMM& pmm) : NEW_SIZE(pmm.colsize()) { TMVAssert(Attrib::symmatrixok); TMVAssert(pmm.colsize() == pmm.rowsize()); TMVAssert(pmm.getM1().isSameAs(pmm.getM2().adjoint())); TMVAssert(TMV_IMAG(pmm.getX()) == RT(0)); RankKUpdate(pmm.getX(),pmm.getM1(),view()); } template inline HermMatrix(const ProdUL& pmm) : NEW_SIZE(pmm.colsize()) { TMVAssert(Attrib::symmatrixok); TMVAssert(pmm.colsize() == pmm.rowsize()); TMVAssert(pmm.getM1().isSameAs(pmm.getM2().adjoint())); TMVAssert(TMV_IMAG(pmm.getX()) == RT(0)); RankKUpdate(pmm.getX(),pmm.getM1(),view()); } template inline HermMatrix(const ProdLU& pmm) : NEW_SIZE(pmm.colsize()) { TMVAssert(Attrib::symmatrixok); TMVAssert(pmm.colsize() == pmm.rowsize()); TMVAssert(pmm.getM1().isSameAs(pmm.getM2().adjoint())); TMVAssert(TMV_IMAG(pmm.getX()) == RT(0)); RankKUpdate(pmm.getX(),pmm.getM1(),view()); } #undef NEW_SIZE virtual inline ~HermMatrix() { TMV_SETFIRSTLAST(0,0); #ifdef TMV_EXTRA_DEBUG setAllTo(T(999)); #endif } // // Op= // inline type& operator=(const type& m2) { TMVAssert(m2.size() == size()); if (&m2 != this) std::copy(m2.cptr(),m2.cptr()+itslen,itsm.get()); return *this; } inline type& operator=(const GenSymMatrix& m2) { TMVAssert(m2.size() == size()); TMVAssert(m2.isherm()); m2.assignToS(view()); return *this; } inline type& operator=(const GenSymMatrix& m2) { TMVAssert(isComplex(T())); TMVAssert(m2.size() == size()); TMVAssert(m2.isherm()); m2.assignToS(view()); return *this; } template inline type& operator=(const GenSymMatrix& m2) { TMVAssert(m2.size() == size()); TMVAssert(m2.isherm()); upperTri() = m2.upperTri(); return *this; } inline type& operator=(const T& x) { TMVAssert(TMV_IMAG(x) == RT(0)); return setToIdentity(x); } inline type& operator=(const AssignableToSymMatrix& m2) { TMVAssert(size() == m2.colsize()); TMVAssert(m2.isherm()); m2.assignToS(view()); return *this; } inline type& operator=(const AssignableToSymMatrix& m2) { TMVAssert(isComplex(T())); TMVAssert(size() == m2.colsize()); TMVAssert(m2.isherm()); m2.assignToS(view()); return *this; } inline type& operator=(const GenDiagMatrix& m2) { TMVAssert(size() == m2.colsize()); view() = m2; return *this; } inline type& operator=(const GenDiagMatrix& m2) { TMVAssert(isComplex(T())); TMVAssert(size() == m2.colsize()); view() = m2; TMVAssert(this->isHermOK()); return *this; } template inline type& operator=(const OProdVV& opvv) { TMVAssert(size() == opvv.colsize()); TMVAssert(size() == opvv.rowsize()); TMVAssert(opvv.getV1().isSameAs(opvv.getV2().conjugate())); Rank1Update(opvv.getX(),opvv.getV1(),view()); return *this; } template inline type& operator=(const ProdMM& pmm) { TMVAssert(size() == pmm.colsize()); TMVAssert(size() == pmm.rowsize()); TMVAssert(pmm.getM1().isSameAs(pmm.getM2().adjoint())); RankKUpdate(pmm.getX(),pmm.getM1(),view()); return *this; } template inline type& operator=(const ProdUL& pmm) { TMVAssert(size() == pmm.colsize()); TMVAssert(size() == pmm.rowsize()); TMVAssert(pmm.getM1().isSameAs(pmm.getM2().adjoint())); RankKUpdate(pmm.getX(),pmm.getM1(),view()); return *this; } template inline type& operator=(const ProdLU& pmm) { TMVAssert(size() == pmm.colsize()); TMVAssert(size() == pmm.rowsize()); TMVAssert(pmm.getM1().isSameAs(pmm.getM2().adjoint())); RankKUpdate(pmm.getX(),pmm.getM1(),view()); return *this; } // // Access // inline T operator()(ptrdiff_t i, ptrdiff_t j) const { if (I==int(CStyle)) { TMVAssert(i>=0 && i=0 && j0 && i<=size()); TMVAssert(j>0 && j<=size()); return cref(i-1,j-1); } } inline reference operator()(ptrdiff_t i, ptrdiff_t j) { if (I==int(CStyle)) { TMVAssert(i>=0 && i=0 && j0 && i<=size()); TMVAssert(j>0 && j<=size()); return ref(i-1,j-1); } } inline const_vec_type row(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2) const { if (I==int(FortranStyle)) { TMVAssert(i>0 && i<=size()); --i; TMVAssert(j1>0 && j1-j2<=0 && j2<=size()); --j1; } else { TMVAssert(i>=0 && i=0 && j1-j2<=0 && j2<=size()); } if ((uplo()==Upper && i-j1<=0) || (uplo()==Lower && j2-i<=1)) return const_vec_type( itsm.get()+i*stepi()+j1*stepj(), j2-j1,stepj(),NonConj); else return const_vec_type( itsm.get()+i*stepj()+j1*stepi(), j2-j1,stepi(),TMV_ConjOf(T,NonConj)); } inline const_vec_type col(ptrdiff_t j, ptrdiff_t i1, ptrdiff_t i2) const { if (I==int(FortranStyle)) { TMVAssert(j>0 && j<=size()); --j; TMVAssert(i1>0 && i1-i2<=0 && i2<=size()); --i1; } else { TMVAssert(j>=0 && j=0 && i1-i2<=0 && i2<=size()); } if ((uplo()==Upper && i2-j<=1) || (uplo()==Lower && j-i1<=0)) return const_vec_type( itsm.get()+i1*stepi()+j*stepj(), i2-i1,stepi(),NonConj); else return const_vec_type( itsm.get()+i1*stepj()+j*stepi(), i2-i1,stepj(),TMV_ConjOf(T,NonConj)); } inline const_vec_type diag() const { return const_vec_type( itsm.get(),size(),stepi()+stepj(),NonConj); } inline const_vec_type diag(ptrdiff_t i) const { TMVAssert(i>=-size() && i<=size()); ConjType newct = ((i>0) == (uplo()==Upper)) ? NonConj : TMV_ConjOf(T,NonConj); i = std::abs(i); TMVAssert(i<=size()); return const_vec_type( itsm.get()+i*(uplo()==Upper?stepj():stepi()), size()-i,stepi()+stepj(),newct); } inline const_vec_type diag(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2) const { TMVAssert(i>=-size() && i<=size()); if (I==int(FortranStyle)) { TMVAssert(j1>0 && j1-j2<=0 && j2<=size()-std::abs(i)); --j1; } else { TMVAssert(j1>=0 && j1-j2<=0 && j2<=size()-std::abs(i)); } ConjType newct = ((i>0) == (uplo()==Upper)) ? NonConj : TMV_ConjOf(T,NonConj); i = std::abs(i); const ptrdiff_t ds = stepi()+stepj(); return const_vec_type( itsm.get()+i*(uplo()==Upper?stepj():stepi())+j1*ds, j2-j1,ds,newct); } inline vec_type row(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2) { if (I==int(FortranStyle)) { TMVAssert(i>0 && i<=size()); --i; TMVAssert(j1>0 && j1-j2<=0 && j2<=size()); --j1; } else { TMVAssert(i>=0 && i=0 && j1-j2<=0 && j2<=size()); } if ((uplo()==Upper && i-j1<=0) || (uplo()==Lower && j2-i<=1)) return vec_type( itsm.get()+i*stepi()+j1*stepj(), j2-j1,stepj(),NonConj TMV_FIRSTLAST); else return vec_type( itsm.get()+i*stepj()+j1*stepi(), j2-j1,stepi(),TMV_ConjOf(T,NonConj) TMV_FIRSTLAST); } inline vec_type col(ptrdiff_t j, ptrdiff_t i1, ptrdiff_t i2) { if (I==int(FortranStyle)) { TMVAssert(j>0 && j<=size()); --j; TMVAssert(i1>0 && i1-i2<=0 && i2<=size()); --i1; } else { TMVAssert(j>=0 && j=0 && i1-i2<=0 && i2<=size()); } if ((uplo()==Upper && i2-j<=1) || (uplo()==Lower && j-i1<=0)) return vec_type( itsm.get()+i1*stepi()+j*stepj(), i2-i1,stepi(),NonConj TMV_FIRSTLAST); else return vec_type( itsm.get()+i1*stepj()+j*stepi(), i2-i1,stepj(),TMV_ConjOf(T,NonConj) TMV_FIRSTLAST); } inline vec_type diag() { return vec_type( itsm.get(),size(),stepi()+stepj(),NonConj TMV_FIRSTLAST); } inline vec_type diag(ptrdiff_t i) { TMVAssert(i>=-size() && i<=size()); ConjType newct = ((i>0) == (uplo()==Upper)) ? NonConj : TMV_ConjOf(T,NonConj); i = std::abs(i); TMVAssert(i<=size()); return vec_type( itsm.get()+i*(uplo()==Upper?stepj():stepi()),size()-i, stepi()+stepj(),newct TMV_FIRSTLAST); } inline vec_type diag(ptrdiff_t i, ptrdiff_t j1, ptrdiff_t j2) { TMVAssert(i>=-size() && i<=size()); if (I==int(FortranStyle)) { TMVAssert(j1>0 && j1-j2<=0 && j2<=size()-std::abs(i)); --j1; } else { TMVAssert(j1>=0 && j1-j2<=0 && j2<=size()-std::abs(i)); } ConjType newct = ((i>0) == (uplo()==Upper)) ? NonConj : TMV_ConjOf(T,NonConj); i = std::abs(i); const ptrdiff_t ds = stepi()+stepj(); return vec_type( itsm.get()+i*(uplo()==Upper?stepj():stepi())+j1*ds, j2-j1,ds,newct TMV_FIRSTLAST); } // // Modifying Functions // inline type& setZero() { std::fill_n(itsm.get(),itslen,T(0)); return *this; } inline type& setAllTo(const T& x) { TMVAssert(TMV_IMAG(x) == RT(0)); upperTri().setAllTo(x); return *this; } inline type& addToAll(const T& x) { TMVAssert(TMV_IMAG(x) == RT(0)); upperTri().addToAll(x); return *this; } inline type& clip(RT thresh) { upperTri().clip(thresh); return *this; } inline type& conjugateSelf() { if (isComplex(T())) upperTri().conjugateSelf(); return *this; } inline type& transposeSelf() { conjugateSelf(); } inline type& setToIdentity(const T& x=T(1)) { TMVAssert(TMV_IMAG(x) == RT(0)); setZero(); diag().setAllTo(x); return *this; } inline type& swapRowsCols(ptrdiff_t i1, ptrdiff_t i2) { view().swapRowsCols(i1,i2); return *this; } inline type& permuteRowsCols(const ptrdiff_t* p, ptrdiff_t i1, ptrdiff_t i2) { view().permuteRowsCols(p,i1,i2); return *this; } inline type& reversePermuteRowsCols(const ptrdiff_t* p, ptrdiff_t i1, ptrdiff_t i2) { view().reversePermuteRowsCols(p,i1,i2); return *this; } inline type& permuteRowsCols(const ptrdiff_t* p) { view().permuteRowsCols(p); return *this; } inline type& reversePermuteRowsCols(const ptrdiff_t* p) { view().reversePermuteRowsCols(p); return *this; } // // subMatrix // inline const_rec_type subMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2) const { TMVAssert(view().hasSubMatrix(i1,i2,j1,j2,1,1)); if (I==int(FortranStyle)) { --i1; --j1; } if ((uplo()==Upper && i2-j1<=1) || (uplo()==Lower && j2-i1<=1)) return const_rec_type( itsm.get()+i1*stepi()+j1*stepj(), i2-i1,j2-j1,stepi(),stepj(),NonConj); else return const_rec_type( itsm.get()+i1*stepj()+j1*stepi(),i2-i1,j2-j1, stepj(),stepi(),TMV_ConjOf(T,NonConj)); } inline const_rec_type subMatrix( ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2, ptrdiff_t istep, ptrdiff_t jstep) const { TMVAssert(view().hasSubMatrix(i1,i2,j1,j2,istep,jstep)); if (I==int(FortranStyle)) { --i1; --j1; i2+=istep-1; j2+=jstep-1; } if ((uplo()==Upper && i2-j1<=istep) || (uplo()==Lower && j2-i1<=jstep)) return const_rec_type( itsm.get()+i1*stepi()+j1*stepj(), (i2-i1)/istep,(j2-j1)/jstep,istep*stepi(),jstep*stepj(), NonConj); else return const_rec_type( itsm.get()+i1*stepj()+j1*stepi(), (i2-i1)/istep,(j2-j1)/jstep,istep*stepj(),jstep*stepi(), TMV_ConjOf(T,NonConj)); } inline const_vec_type subVector( ptrdiff_t i, ptrdiff_t j, ptrdiff_t istep, ptrdiff_t jstep, ptrdiff_t n) const { TMVAssert(base::hasSubVector(i,j,istep,jstep,n)); if ((uplo()==Upper && i-j<=0) || (uplo()==Lower && j-i<=0)) return const_vec_type( itsm.get()+i*stepi()+j*stepj(),n, istep*stepi()+jstep*stepj(),NonConj); else return const_vec_type( itsm.get()+i*stepj()+j*stepi(),n, istep*stepj()+jstep*stepi(),TMV_ConjOf(T,NonConj)); } inline const_view_type subSymMatrix(ptrdiff_t i1, ptrdiff_t i2) const { TMVAssert(view().hasSubSymMatrix(i1,i2,1)); if (I==int(FortranStyle)) { --i1; } return const_view_type( itsm.get()+i1*(stepi()+stepj()), i2-i1,stepi(),stepj(),Herm,uplo(),NonConj); } inline const_view_type subSymMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t istep) const { TMVAssert(view().hasSubSymMatrix(i1,i2,istep)); if (I==int(FortranStyle)) { --i1; i2+=istep-1; } return const_view_type( itsm.get()+i1*(stepi()+stepj()), (i2-i1)/istep,istep*stepi(),istep*stepj(),Herm,uplo(), NonConj); } inline const_uppertri_type upperTri(DiagType dt = NonUnitDiag) const { return uplo()==Upper ? const_uppertri_type( itsm.get(),size(),stepi(),stepj(),dt,NonConj) : const_uppertri_type( itsm.get(),size(),stepj(),stepi(), dt,TMV_ConjOf(T,NonConj)); } inline const_uppertri_type unitUpperTri() const { return uplo()==Upper ? const_uppertri_type( itsm.get(),size(),stepi(),stepj(),UnitDiag,NonConj) : const_uppertri_type( itsm.get(),size(),stepj(),stepi(), UnitDiag,TMV_ConjOf(T,NonConj)); } inline const_lowertri_type lowerTri(DiagType dt = NonUnitDiag) const { return uplo()==Lower ? const_lowertri_type( itsm.get(),size(),stepi(),stepj(),dt,NonConj) : const_lowertri_type( itsm.get(),size(),stepj(),stepi(), dt,TMV_ConjOf(T,NonConj)); } inline const_lowertri_type unitLowerTri() const { return uplo()==Lower ? const_lowertri_type( itsm.get(),size(),stepi(),stepj(),UnitDiag,NonConj) : const_lowertri_type( itsm.get(),size(),stepj(),stepi(), UnitDiag,TMV_ConjOf(T,NonConj)); } inline const_realpart_type realPart() const { return const_realpart_type( reinterpret_cast(itsm.get()),size(), isReal(T()) ? stepi() : 2*stepi(), isReal(T()) ? stepj() : 2*stepj(), Herm,uplo(),NonConj); } inline const_realpart_type imagPart() const { // The imaginary part of a Hermitian matrix is anti-symmetric // so this is illegal. TMVAssert(TMV_FALSE); return const_realpart_type(0,0,0,0,Herm,uplo(),NonConj); } inline const_view_type view() const { return const_view_type( itsm.get(),size(),stepi(),stepj(),Herm,uplo(),NonConj); } inline const_view_type transpose() const { return const_view_type( itsm.get(),size(),stepj(),stepi(), Herm,TMV_UTransOf(U),NonConj); } inline const_view_type conjugate() const { return const_view_type( itsm.get(),size(),stepi(),stepj(), Herm,uplo(),TMV_ConjOf(T,NonConj)); } inline const_view_type adjoint() const { return const_view_type( itsm.get(),size(),stepj(),stepi(), Herm,TMV_UTransOf(U),TMV_ConjOf(T,NonConj)); } inline rec_type subMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2) { TMVAssert(view().hasSubMatrix(i1,i2,j1,j2,1,1)); if (I==int(FortranStyle)) { --i1; --j1; } if ((uplo()==Upper && i2-j1<=1) || (uplo()==Lower && j2-i1<=1)) return rec_type( itsm.get()+i1*stepi()+j1*stepj(), i2-i1,j2-j1,stepi(),stepj(),NonConj TMV_FIRSTLAST); else return rec_type( itsm.get()+i1*stepj()+j1*stepi(), i2-i1,j2-j1,stepj(),stepi(), TMV_ConjOf(T,NonConj) TMV_FIRSTLAST); } inline rec_type subMatrix( ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t j1, ptrdiff_t j2, ptrdiff_t istep, ptrdiff_t jstep) { TMVAssert(view().hasSubMatrix(i1,i2,j1,j2,istep,jstep)); if (I==int(FortranStyle)) { --i1; --j1; i2+=istep-1; j2+=jstep-1; } if ((uplo()==Upper && i2-j1<=istep) || (uplo()==Lower && j2-i1<=jstep)) return rec_type( itsm.get()+i1*stepi()+j1*stepj(), (i2-i1)/istep,(j2-j1)/jstep,istep*stepi(),jstep*stepj(), NonConj TMV_FIRSTLAST); else return rec_type( itsm.get()+i1*stepj()+j1*stepi(), (i2-i1)/istep,(j2-j1)/jstep,istep*stepj(),jstep*stepi(), TMV_ConjOf(T,NonConj) TMV_FIRSTLAST); } inline vec_type subVector( ptrdiff_t i, ptrdiff_t j, ptrdiff_t istep, ptrdiff_t jstep, ptrdiff_t n) { TMVAssert(base::hasSubVector(i,j,istep,jstep,n)); if ((uplo()==Upper && i-j<=0) || (uplo()==Lower && j-i<=0)) return vec_type( itsm.get()+i*stepi()+j*stepj(),n, istep*stepi()+jstep*stepj(),NonConj TMV_FIRSTLAST); else return vec_type( itsm.get()+i*stepj()+j*stepi(),n, istep*stepj()+jstep*stepi(),TMV_ConjOf(T,NonConj) TMV_FIRSTLAST); } inline view_type subSymMatrix(ptrdiff_t i1, ptrdiff_t i2) { TMVAssert(view().hasSubSymMatrix(i1,i2,1)); if (I==int(FortranStyle)) { --i1; } return view_type( itsm.get()+i1*(stepi()+stepj()), i2-i1,stepi(),stepj(),Herm,uplo(),NonConj TMV_FIRSTLAST); } inline view_type subSymMatrix(ptrdiff_t i1, ptrdiff_t i2, ptrdiff_t istep) { TMVAssert(view().hasSubSymMatrix(i1,i2,istep)); if (I==int(FortranStyle)) { --i1; i2+=istep-1; } return view_type( itsm.get()+i1*(stepi()+stepj()), (i2-i1)/istep,istep*stepi(),istep*stepj(),Herm,uplo(), NonConj TMV_FIRSTLAST); } inline uppertri_type upperTri(DiagType dt = NonUnitDiag) { return uplo()==Upper ? uppertri_type( itsm.get(),size(),stepi(),stepj(),dt,NonConj TMV_FIRSTLAST) : uppertri_type( itsm.get(),size(),stepj(),stepi(),dt,TMV_ConjOf(T,NonConj) TMV_FIRSTLAST); } inline uppertri_type unitUpperTri() { return uplo()==Upper ? uppertri_type( itsm.get(),size(),stepi(),stepj(),UnitDiag,NonConj TMV_FIRSTLAST) : uppertri_type( itsm.get(),size(),stepj(),stepi(), UnitDiag,TMV_ConjOf(T,NonConj) TMV_FIRSTLAST); } inline lowertri_type lowerTri(DiagType dt = NonUnitDiag) { return uplo()==Lower ? lowertri_type( itsm.get(),size(),stepi(),stepj(),dt,NonConj TMV_FIRSTLAST) : lowertri_type( itsm.get(),size(),stepj(),stepi(), dt,TMV_ConjOf(T,NonConj) TMV_FIRSTLAST); } inline lowertri_type unitLowerTri() { return uplo()==Lower ? lowertri_type( itsm.get(),size(),stepi(),stepj(),UnitDiag,NonConj TMV_FIRSTLAST) : lowertri_type( itsm.get(),size(),stepj(),stepi(), UnitDiag,TMV_ConjOf(T,NonConj) TMV_FIRSTLAST); } inline realpart_type realPart() { return realpart_type( reinterpret_cast( itsm.get()),size(), isReal(T()) ? stepi() : 2*stepi(), isReal(T()) ? stepj() : 2*stepj(), Herm,uplo(),NonConj #ifdef TMVFLDEBUG ,reinterpret_cast(_first) ,reinterpret_cast(_last) #endif ); } inline realpart_type imagPart() { // The imaginary part of a Hermitian matrix is anti-symmetric // so this is illegal. TMVAssert(TMV_FALSE); return realpart_type(0,0,0,0,Herm,uplo(),NonConj TMV_FIRSTLAST1(0,0) ); } inline view_type view() { return view_type( itsm.get(),size(),stepi(),stepj(),Herm,uplo(),NonConj TMV_FIRSTLAST); } inline view_type transpose() { return view_type( itsm.get(),size(),stepj(),stepi(),Herm,TMV_UTransOf(U),NonConj TMV_FIRSTLAST); } inline view_type conjugate() { return view_type( itsm.get(),size(),stepi(),stepj(), Herm,uplo(),TMV_ConjOf(T,NonConj) TMV_FIRSTLAST); } inline view_type adjoint() { return view_type( itsm.get(),size(),stepj(),stepi(), Herm,TMV_UTransOf(U),TMV_ConjOf(T,NonConj) TMV_FIRSTLAST); } // // I/O // void read(const TMV_Reader& reader); inline ptrdiff_t size() const { return itss; } inline const T* cptr() const { return itsm.get(); } inline T* ptr() { return itsm.get(); } inline ptrdiff_t stepi() const { return S==int(RowMajor) ? itss : 1; } inline ptrdiff_t stepj() const { return S==int(RowMajor) ? 1 : itss; } inline SymType sym() const { return Herm; } inline UpLoType uplo() const { return static_cast(U); } inline ConjType ct() const { return NonConj; } inline bool isrm() const { return S==int(RowMajor); } inline bool iscm() const { return S==int(ColMajor); } inline bool isconj() const { return false; } inline bool isherm() const { return true; } inline bool issym() const { return isReal(T()); } inline bool isupper() const { return U==int(Upper); } inline reference ref(ptrdiff_t i, ptrdiff_t j) { if ((uplo()==Upper && i <= j) || (uplo()==Lower && i>=j)) return RefHelper::makeRef( itsm.get() + i*stepi() + j*stepj(),NonConj); else return RefHelper::makeRef( itsm.get() + j*stepi() + i*stepj(),Conj); } inline T cref(ptrdiff_t i, ptrdiff_t j) const { if ((uplo()==Upper && i <= j) || (uplo()==Lower && i>=j)) return itsm.get()[i*stepi() + j*stepj()]; else return TMV_CONJ(itsm.get()[j*stepi() + i*stepj()]); } inline void resize(ptrdiff_t s) { TMVAssert(s >= 0); itslen = s*s; itsm.resize(itslen); itss = s; DivHelper::resetDivType(); #ifdef TMVFLDEBUG _first = itsm.get(); _last = _first+itslen; #endif #ifdef TMV_EXTRA_DEBUG setAllTo(T(888)); #else if (isComplex(T())) diag().imagPart().setZero(); #endif } protected : ptrdiff_t itslen; AlignedArray itsm; ptrdiff_t itss; #ifdef TMVFLDEBUG public: const T* _first; const T* _last; #endif friend void Swap(HermMatrix& m1, HermMatrix& m2) { TMVAssert(m1.size() == m2.size()); m1.itsm.swapWith(m2.itsm); #ifdef TMVFLDEBUG TMV_SWAP(m1._first,m2._first); TMV_SWAP(m1._last,m2._last); #endif } }; // HermMatrix //------------------------------------------------------------------------- // // Special Creators: // SymMatrixViewOf(m,uplo) // HermMatrixViewOf(m,uplo) // SymMatrixViewOf(mptr,size,uplo,stor) // HermMatrixViewOf(mptr,size,uplo,stor) // SymMatrixViewOf(mptr,size,uplo,stepi,stepj) // HermMatrixViewOf(mptr,size,uplo,stepi,stepj) // template inline ConstSymMatrixView SymMatrixViewOf( const GenMatrix& m, UpLoType uplo) { TMVAssert(m.colsize()==m.rowsize()); return ConstSymMatrixView( m.cptr(),m.rowsize(),m.stepi(),m.stepj(),Sym,uplo,m.ct()); } template inline ConstSymMatrixView SymMatrixViewOf( const ConstMatrixView& m, UpLoType uplo) { TMVAssert(m.colsize()==m.rowsize()); return ConstSymMatrixView( m.cptr(),m.rowsize(),m.stepi(),m.stepj(),Sym,uplo,m.ct()); } template inline ConstSymMatrixView SymMatrixViewOf( const Matrix& m, UpLoType uplo) { TMVAssert(m.colsize()==m.rowsize()); return ConstSymMatrixView( m.cptr(),m.rowsize(),m.stepi(),m.stepj(),Sym,uplo,m.ct()); } template inline SymMatrixView SymMatrixViewOf( MatrixView m, UpLoType uplo) { TMVAssert(m.colsize()==m.rowsize()); return SymMatrixView( m.ptr(),m.rowsize(),m.stepi(),m.stepj(),Sym,uplo,m.ct() TMV_FIRSTLAST1(m._first,m._last)); } template inline SymMatrixView SymMatrixViewOf( Matrix& m, UpLoType uplo) { TMVAssert(m.colsize()==m.rowsize()); return SymMatrixView( m.ptr(),m.rowsize(),m.stepi(),m.stepj(),Sym,uplo,m.ct() TMV_FIRSTLAST1(m._first,m._last)); } template inline ConstSymMatrixView HermMatrixViewOf( const GenMatrix& m, UpLoType uplo) { TMVAssert(m.colsize()==m.rowsize()); TMVAssert(isReal(T()) || m.diag().imagPart().normInf() == TMV_RealType(T)(0)); return ConstSymMatrixView( m.cptr(),m.rowsize(),m.stepi(),m.stepj(),Herm,uplo,m.ct()); } template inline ConstSymMatrixView HermMatrixViewOf( const ConstMatrixView& m, UpLoType uplo) { TMVAssert(m.colsize()==m.rowsize()); TMVAssert(isReal(T()) || m.diag().imagPart().normInf() == TMV_RealType(T)(0)); return ConstSymMatrixView( m.cptr(),m.rowsize(),m.stepi(),m.stepj(),Herm,uplo,m.ct()); } template inline ConstSymMatrixView HermMatrixViewOf( const Matrix& m, UpLoType uplo) { TMVAssert(m.colsize()==m.rowsize()); TMVAssert(isReal(T()) || m.diag().imagPart().normInf() == TMV_RealType(T)(0)); return ConstSymMatrixView( m.cptr(),m.rowsize(),m.stepi(),m.stepj(),Herm,uplo,m.ct()); } template inline SymMatrixView HermMatrixViewOf( MatrixView m, UpLoType uplo) { TMVAssert(m.colsize()==m.rowsize()); TMVAssert(isReal(T()) || m.diag().imagPart().normInf() == TMV_RealType(T)(0)); return SymMatrixView( m.ptr(),m.rowsize(),m.stepi(),m.stepj(),Herm,uplo,m.ct() TMV_FIRSTLAST1(m._first,m._last)); } template inline SymMatrixView HermMatrixViewOf( Matrix& m, UpLoType uplo) { TMVAssert(m.colsize()==m.rowsize()); TMVAssert(isReal(T()) || m.diag().imagPart().normInf() == TMV_RealType(T)(0)); return SymMatrixView( m.ptr(),m.rowsize(),m.stepi(),m.stepj(),Herm,uplo,m.ct() TMV_FIRSTLAST1(m._first,m._last)); } template inline ConstSymMatrixView SymMatrixViewOf( const T* m, ptrdiff_t size, UpLoType uplo, StorageType stor) { TMVAssert(stor == RowMajor || stor == ColMajor); TMVAssert(size>=0); const ptrdiff_t stepi = stor == RowMajor ? size : 1; const ptrdiff_t stepj = stor == RowMajor ? 1 : size; return ConstSymMatrixView( m,size,stepi,stepj,Sym,uplo,NonConj); } template inline ConstSymMatrixView HermMatrixViewOf( const T* m, ptrdiff_t size, UpLoType uplo, StorageType stor) { TMVAssert(stor == RowMajor || stor == ColMajor); TMVAssert(size>=0); const ptrdiff_t stepi = stor == RowMajor ? size : 1; const ptrdiff_t stepj = stor == RowMajor ? 1 : size; return ConstSymMatrixView(m,size,stepi,stepj,Herm,uplo,NonConj); } template inline SymMatrixView SymMatrixViewOf( T* m, ptrdiff_t size, UpLoType uplo, StorageType stor) { TMVAssert(stor == RowMajor || stor == ColMajor); TMVAssert(size>=0); const ptrdiff_t stepi = stor == RowMajor ? size : 1; const ptrdiff_t stepj = stor == RowMajor ? 1 : size; return SymMatrixView( m,size,stepi,stepj,Sym,uplo,NonConj TMV_FIRSTLAST1(m,m+size*size)); } template inline SymMatrixView HermMatrixViewOf( T* m, ptrdiff_t size, UpLoType uplo, StorageType stor) { TMVAssert(stor == RowMajor || stor == ColMajor); TMVAssert(size>=0); const ptrdiff_t stepi = stor == RowMajor ? size : 1; const ptrdiff_t stepj = stor == RowMajor ? 1 : size; return SymMatrixView( m,size,stepi,stepj,Herm,uplo,NonConj TMV_FIRSTLAST1(m,m+size*size)); } template inline ConstSymMatrixView SymMatrixViewOf( const T* m, ptrdiff_t size, UpLoType uplo, ptrdiff_t stepi, ptrdiff_t stepj) { TMVAssert(size>=0); return ConstSymMatrixView( m,size,stepi,stepj,Sym,uplo,NonConj); } template inline ConstSymMatrixView HermMatrixViewOf( const T* m, ptrdiff_t size, UpLoType uplo, ptrdiff_t stepi, ptrdiff_t stepj) { TMVAssert(size>=0); return ConstSymMatrixView( m,size,stepi,stepj,Herm,uplo,NonConj); } template inline SymMatrixView SymMatrixViewOf( T* m, ptrdiff_t size, UpLoType uplo, ptrdiff_t stepi, ptrdiff_t stepj) { TMVAssert(size>=0); return SymMatrixView( m,size,stepi,stepj,Sym,uplo,NonConj TMV_FIRSTLAST1(m,m+size*size)); } template inline SymMatrixView HermMatrixViewOf( T* m, ptrdiff_t size, UpLoType uplo, ptrdiff_t stepi, ptrdiff_t stepj) { TMVAssert(size>=0); return SymMatrixView( m,size,stepi,stepj,Herm,uplo,NonConj TMV_FIRSTLAST1(m,m+size*size)); } // // Swap Matrices // template inline void Swap(SymMatrixView m1, SymMatrixView m2) { TMVAssert(m1.size() == m2.size()); TMVAssert(m1.issym() == m2.issym()); TMVAssert(m1.isherm() == m2.isherm()); Swap(m1.upperTri(),m2.upperTri()); } template inline void Swap(SymMatrixView m1, SymMatrix& m2) { Swap(m1,m2.view()); } template inline void Swap(SymMatrix& m1, SymMatrixView m2) { Swap(m1.view(),m2); } template inline void Swap(SymMatrix& m1, SymMatrix& m2) { Swap(m1.view(),m2.view()); } template inline void Swap(SymMatrixView m1, HermMatrix& m2) { Swap(m1,m2.view()); } template inline void Swap(HermMatrix& m1, SymMatrixView m2) { Swap(m1.view(),m2); } template inline void Swap(HermMatrix& m1, HermMatrix& m2) { Swap(m1.view(),m2.view()); } // // Views: // template inline ConstSymMatrixView Transpose(const GenSymMatrix& m) { return m.transpose(); } template inline ConstSymMatrixView Transpose(const ConstSymMatrixView& m) { return m.transpose(); } template inline ConstSymMatrixView Transpose( const SymMatrix& m) { return m.transpose(); } template inline ConstSymMatrixView Transpose( const HermMatrix& m) { return m.transpose(); } template inline SymMatrixView Transpose(SymMatrixView m) { return m.transpose(); } template inline SymMatrixView Transpose(SymMatrix& m) { return m.transpose(); } template inline SymMatrixView Transpose(HermMatrix& m) { return m.transpose(); } template inline ConstSymMatrixView Conjugate(const GenSymMatrix& m) { return m.conjugate(); } template inline ConstSymMatrixView Conjugate(const ConstSymMatrixView& m) { return m.conjugate(); } template inline ConstSymMatrixView Conjugate( const SymMatrix& m) { return m.conjugate(); } template inline ConstSymMatrixView Conjugate( const HermMatrix& m) { return m.conjugate(); } template inline SymMatrixView Conjugate(SymMatrixView m) { return m.conjugate(); } template inline SymMatrixView Conjugate(SymMatrix& m) { return m.conjugate(); } template inline SymMatrixView Conjugate(HermMatrix& m) { return m.conjugate(); } template inline ConstSymMatrixView Adjoint(const GenSymMatrix& m) { return m.adjoint(); } template inline ConstSymMatrixView Adjoint(const ConstSymMatrixView& m) { return m.adjoint(); } template inline ConstSymMatrixView Adjoint( const SymMatrix& m) { return m.adjoint(); } template inline ConstSymMatrixView Adjoint( const HermMatrix& m) { return m.adjoint(); } template inline SymMatrixView Adjoint(SymMatrixView m) { return m.adjoint(); } template inline SymMatrixView Adjoint(SymMatrix& m) { return m.adjoint(); } template inline SymMatrixView Adjoint(HermMatrix& m) { return m.adjoint(); } template inline QuotXS Inverse(const GenSymMatrix& m) { return m.inverse(); } // // SymMatrix ==, != SymMatrix // template inline bool operator==( const GenSymMatrix& m1, const GenSymMatrix& m2) { return m1.upperTri() == m2.upperTri(); } template inline bool operator!=( const GenSymMatrix& m1, const GenSymMatrix& m2) { return !(m1 == m2); } template inline bool operator==( const GenSymMatrix& m1, const GenMatrix& m2) { return m1.upperTri() == m2.upperTri() && m1.lowerTri() == m2.lowerTri(); } template inline bool operator==( const GenMatrix& m1, const GenSymMatrix& m2) { return m2 == m1; } template inline bool operator!=( const GenSymMatrix& m1, const GenMatrix& m2) { return !(m1 == m2); } template inline bool operator!=( const GenMatrix& m1, const GenSymMatrix& m2) { return !(m1 == m2); } // // I/O // template inline std::istream& operator>>(std::istream& is, SymMatrixView m) { return is >> IOStyle() >> m; } template inline std::istream& operator>>(std::istream& is, SymMatrix& m) { return is >> IOStyle() >> m; } template inline std::istream& operator>>(std::istream& is, HermMatrix& m) { return is >> IOStyle() >> m; } template inline std::istream& operator>>( const TMV_Reader& reader, SymMatrixView m) { m.read(reader); return reader.getis(); } template inline std::istream& operator>>( const TMV_Reader& reader, SymMatrix& m) { m.read(reader); return reader.getis(); } template inline std::istream& operator>>( const TMV_Reader& reader, HermMatrix& m) { m.read(reader); return reader.getis(); } } // namespace tmv #endif