void HermitianFromEVD ( UpperOrLower uplo, Matrix<F>& A, const Matrix<Base<F>>& w, const Matrix<F>& Z ) { DEBUG_CSE Matrix<F> Z1Copy, Y1; const Int m = Z.Height(); const Int n = Z.Width(); A.Resize( m, m ); if( uplo == LOWER ) MakeTrapezoidal( UPPER, A, 1 ); else MakeTrapezoidal( LOWER, A, -1 ); const Int bsize = Blocksize(); for( Int k=0; k<n; k+=bsize ) { const Int nb = Min(bsize,n-k); auto Z1 = Z( ALL, IR(k,k+nb) ); auto w1 = w( IR(k,k+nb), ALL ); Y1 = Z1Copy = Z1; DiagonalScale( RIGHT, NORMAL, w1, Y1 ); Trrk( uplo, NORMAL, ADJOINT, F(1), Z1Copy, Y1, F(1), A ); } }
inline void HermitianFromEVD ( UpperOrLower uplo, Matrix<F>& A, const Matrix<Base<F>>& w, const Matrix<F>& Z ) { DEBUG_ONLY(CallStackEntry cse("HermitianFromEVD")) Matrix<F> Z1Copy, Y1; const Int m = Z.Height(); const Int n = Z.Width(); A.Resize( m, m ); if( uplo == LOWER ) MakeTrapezoidal( UPPER, A, 1 ); else MakeTrapezoidal( LOWER, A, -1 ); const Int bsize = Blocksize(); for( Int k=0; k<n; k+=bsize ) { const Int nb = Min(bsize,n-k); auto Z1 = LockedView( Z, 0, k, m, nb ); auto w1 = LockedView( w, k, 0, nb, 1 ); Y1 = Z1Copy = Z1; DiagonalScale( RIGHT, NORMAL, w1, Y1 ); Trrk( uplo, NORMAL, ADJOINT, F(1), Z1Copy, Y1, F(1), A ); } }
inline void HermitianFromEVD ( UpperOrLower uplo, Matrix<F>& A, const Matrix<BASE(F)>& w, const Matrix<F>& Z ) { #ifndef RELEASE CallStackEntry entry("HermitianFromEVD"); #endif typedef BASE(F) R; Matrix<F> ZL, ZR, Z0, Z1, Z2; Matrix<R> wT, w0, wB, w1, w2; Matrix<F> Z1Copy, Y1; A.ResizeTo( Z.Height(), Z.Height() ); if( uplo == LOWER ) MakeTrapezoidal( UPPER, A, 1 ); else MakeTrapezoidal( LOWER, A, -1 ); LockedPartitionRight( Z, ZL, ZR, 0 ); LockedPartitionDown ( w, wT, wB, 0 ); while( ZL.Width() < Z.Width() ) { LockedRepartitionRight ( ZL, /**/ ZR, Z0, /**/ Z1, Z2 ); LockedRepartitionDown ( wT, w0, /**/ /**/ w1, wB, w2 ); //--------------------------------------------------------------------// Y1 = Z1Copy = Z1; DiagonalScale( RIGHT, NORMAL, w1, Y1 ); Trrk( uplo, NORMAL, ADJOINT, F(1), Z1Copy, Y1, F(1), A ); //--------------------------------------------------------------------// SlideLockedPartitionDown ( wT, w0, w1, /**/ /**/ wB, w2 ); SlideLockedPartitionRight ( ZL, /**/ ZR, Z0, Z1, /**/ Z2 ); } }
QDWHInfo QDWH( Matrix<F>& A, Matrix<F>& P, const QDWHCtrl& ctrl ) { EL_DEBUG_CSE Matrix<F> ACopy( A ); auto info = QDWH( A, ctrl ); Zeros( P, A.Height(), A.Height() ); Trrk( LOWER, NORMAL, NORMAL, F(1), A, ACopy, F(0), P ); MakeHermitian( LOWER, P ); return info; }
inline void TrdtrmmUVar1( Orientation orientation, Matrix<F>& U ) { #ifndef RELEASE PushCallStack("internal::TrtdrmmUVar1"); if( U.Height() != U.Width() ) throw std::logic_error("U must be square"); if( orientation == NORMAL ) throw std::logic_error("Orientation must be (conjugate-)transpose"); #endif Matrix<F> UTL, UTR, U00, U01, U02, UBL, UBR, U10, U11, U12, U20, U21, U22; Matrix<F> d1, S01; PartitionDownDiagonal ( U, UTL, UTR, UBL, UBR, 0 ); while( UTL.Height() < U.Height() && UTL.Width() < U.Height() ) { RepartitionDownDiagonal ( UTL, /**/ UTR, U00, /**/ U01, U02, /*************/ /******************/ /**/ U10, /**/ U11, U12, UBL, /**/ UBR, U20, /**/ U21, U22 ); //--------------------------------------------------------------------/ U11.GetDiagonal( d1 ); S01 = U01; DiagonalSolve( LEFT, NORMAL, d1, U01, true ); Trrk( UPPER, NORMAL, orientation, F(1), U01, S01, F(1), U00 ); Trmm( RIGHT, UPPER, ADJOINT, UNIT, F(1), U11, U01 ); TrdtrmmUUnblocked( orientation, U11 ); //--------------------------------------------------------------------/ SlidePartitionDownDiagonal ( UTL, /**/ UTR, U00, U01, /**/ U02, /**/ U10, U11, /**/ U12, /*************/ /******************/ UBL, /**/ UBR, U20, U21, /**/ U22 ); } #ifndef RELEASE PopCallStack(); #endif }
inline void TrdtrmmLVar1( Orientation orientation, Matrix<F>& L ) { #ifndef RELEASE CallStackEntry entry("internal::TrdtrmmLVar1"); if( L.Height() != L.Width() ) LogicError("L must be square"); if( orientation == NORMAL ) LogicError("Orientation must be (conjugate-)transpose"); #endif Matrix<F> LTL, LTR, L00, L01, L02, LBL, LBR, L10, L11, L12, L20, L21, L22; Matrix<F> d1, S10; PartitionDownDiagonal ( L, LTL, LTR, LBL, LBR, 0 ); while( LTL.Height() < L.Height() && LTL.Width() < L.Height() ) { RepartitionDownDiagonal ( LTL, /**/ LTR, L00, /**/ L01, L02, /*************/ /******************/ /**/ L10, /**/ L11, L12, LBL, /**/ LBR, L20, /**/ L21, L22 ); //--------------------------------------------------------------------/ L11.GetDiagonal( d1 ); S10 = L10; DiagonalSolve( LEFT, NORMAL, d1, L10, true ); Trrk( LOWER, orientation, NORMAL, F(1), S10, L10, F(1), L00 ); Trmm( LEFT, LOWER, orientation, UNIT, F(1), L11, L10 ); TrdtrmmLUnblocked( orientation, L11 ); //--------------------------------------------------------------------/ SlidePartitionDownDiagonal ( LTL, /**/ LTR, L00, L01, /**/ L02, /**/ L10, L11, /**/ L12, /*************/ /******************/ LBL, /**/ LBR, L20, L21, /**/ L22 ); } }
QDWHInfo QDWH ( AbstractDistMatrix<F>& APre, AbstractDistMatrix<F>& PPre, const QDWHCtrl& ctrl ) { EL_DEBUG_CSE DistMatrixReadWriteProxy<F,F,MC,MR> AProx( APre ); DistMatrixWriteProxy<F,F,MC,MR> PProx( PPre ); auto& A = AProx.Get(); auto& P = PProx.Get(); DistMatrix<F> ACopy( A ); auto info = QDWH( A, ctrl ); Zeros( P, A.Height(), A.Height() ); Trrk( LOWER, NORMAL, NORMAL, F(1), A, ACopy, F(0), P ); MakeHermitian( LOWER, P ); return info; }
inline void TrtrmmUVar1( Orientation orientation, Matrix<T>& U ) { #ifndef RELEASE PushCallStack("internal::TrtrmmUVar1"); #endif Matrix<T> UTL, UTR, U00, U01, U02, UBL, UBR, U10, U11, U12, U20, U21, U22; PartitionDownDiagonal ( U, UTL, UTR, UBL, UBR, 0 ); while( UTL.Height() < U.Height() && UTL.Width() < U.Height() ) { RepartitionDownDiagonal ( UTL, /**/ UTR, U00, /**/ U01, U02, /*************/ /******************/ /**/ U10, /**/ U11, U12, UBL, /**/ UBR, U20, /**/ U21, U22 ); //--------------------------------------------------------------------/ Trrk( UPPER, NORMAL, orientation, T(1), U01, U01, T(1), U00 ); Trmm( RIGHT, UPPER, orientation, NON_UNIT, T(1), U11, U01 ); TrtrmmUUnblocked( orientation, U11 ); //--------------------------------------------------------------------/ SlidePartitionDownDiagonal ( UTL, /**/ UTR, U00, U01, /**/ U02, /**/ U10, U11, /**/ U12, /*************/ /******************/ UBL, /**/ UBR, U20, U21, /**/ U22 ); } #ifndef RELEASE PopCallStack(); #endif }
void UVar1( Matrix<T>& U, bool conjugate=false ) { EL_DEBUG_CSE const Int n = U.Height(); const Int bsize = Blocksize(); const Orientation orientation = ( conjugate ? ADJOINT : TRANSPOSE ); for( Int k=0; k<n; k+=bsize ) { const Int nb = Min(bsize,n-k); const Range<Int> ind0( 0, k ), ind1( k, k+nb ); auto U00 = U( ind0, ind0 ); auto U01 = U( ind0, ind1 ); auto U11 = U( ind1, ind1 ); Trrk( UPPER, NORMAL, orientation, T(1), U01, U01, T(1), U00 ); Trmm( RIGHT, UPPER, orientation, NON_UNIT, T(1), U11, U01 ); trtrmm::UUnblocked( U11, conjugate ); } }
inline void TrtrmmLVar1( Orientation orientation, Matrix<T>& L ) { #ifndef RELEASE CallStackEntry entry("internal::TrtrmmLVar1"); if( orientation == NORMAL ) LogicError("Must be (conjugate-)transposed"); #endif Matrix<T> LTL, LTR, L00, L01, L02, LBL, LBR, L10, L11, L12, L20, L21, L22; PartitionDownDiagonal ( L, LTL, LTR, LBL, LBR, 0 ); while( LTL.Height() < L.Height() && LTL.Width() < L.Height() ) { RepartitionDownDiagonal ( LTL, /**/ LTR, L00, /**/ L01, L02, /*************/ /******************/ /**/ L10, /**/ L11, L12, LBL, /**/ LBR, L20, /**/ L21, L22 ); //--------------------------------------------------------------------/ Trrk( LOWER, orientation, NORMAL, T(1), L10, L10, T(1), L00 ); Trmm( LEFT, LOWER, orientation, NON_UNIT, T(1), L11, L10 ); TrtrmmLUnblocked( orientation, L11 ); //--------------------------------------------------------------------/ SlidePartitionDownDiagonal ( LTL, /**/ LTR, L00, L01, /**/ L02, /**/ L10, L11, /**/ L12, /*************/ /******************/ LBL, /**/ LBR, L20, L21, /**/ L22 ); } }