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 LockedPartitionRight( const DM& A, DM& AL, DM& AR, Int widthAL ) { #ifndef RELEASE PushCallStack("LockedPartitionRight [DistMatrix]"); if( widthAL < 0 ) throw std::logic_error("Width of left partition must be non-negative"); #endif widthAL = std::min(widthAL,A.Width()); const Int widthAR = A.Width()-widthAL; LockedView( AL, A, 0, 0, A.Height(), widthAL ); LockedView( AR, A, 0, widthAL, A.Height(), widthAR ); #ifndef RELEASE PopCallStack(); #endif }
inline void RLHF( int offset, const Matrix<R>& H, Matrix<R>& A ) { #ifndef RELEASE CallStackEntry entry("apply_packed_reflectors::RLHF"); if( offset > 0 || offset < -H.Width() ) throw std::logic_error("Transforms out of bounds"); if( H.Width() != A.Width() ) throw std::logic_error ("Width of transforms must equal width of target matrix"); #endif Matrix<R> HTL, HTR, H00, H01, H02, HPan, HPanCopy, HBL, HBR, H10, H11, H12, H20, H21, H22; Matrix<R> ALeft; Matrix<R> SInv, Z; LockedPartitionDownDiagonal ( H, HTL, HTR, HBL, HBR, 0 ); while( HTL.Height() < H.Height() && HTL.Width() < H.Width() ) { LockedRepartitionDownDiagonal ( HTL, /**/ HTR, H00, /**/ H01, H02, /*************/ /******************/ /**/ H10, /**/ H11, H12, HBL, /**/ HBR, H20, /**/ H21, H22 ); const int HPanWidth = H10.Width() + H11.Width(); const int HPanOffset = std::min( H11.Height(), std::max(-offset-H00.Height(),0) ); const int HPanHeight = H11.Height()-HPanOffset; LockedView ( HPan, H, H00.Height()+HPanOffset, 0, HPanHeight, HPanWidth ); View( ALeft, A, 0, 0, A.Height(), HPanWidth ); //--------------------------------------------------------------------// HPanCopy = HPan; MakeTrapezoidal( RIGHT, LOWER, offset, HPanCopy ); SetDiagonal( RIGHT, offset, HPanCopy, R(1) ); Syrk( UPPER, NORMAL, R(1), HPanCopy, SInv ); HalveMainDiagonal( SInv ); Gemm( NORMAL, TRANSPOSE, R(1), ALeft, HPanCopy, Z ); Trsm( RIGHT, UPPER, NORMAL, NON_UNIT, R(1), SInv, Z ); Gemm( NORMAL, NORMAL, R(-1), Z, HPanCopy, R(1), ALeft ); //--------------------------------------------------------------------// SlideLockedPartitionDownDiagonal ( HTL, /**/ HTR, H00, H01, /**/ H02, /**/ H10, H11, /**/ H12, /*************/ /******************/ HBL, /**/ HBR, H20, H21, /**/ H22 ); } }
inline void LockedRepartitionRight ( const DM& AL, const DM& AR, DM& A0, DM& A1, DM& A2, Int A1Width=Blocksize() ) { DEBUG_ONLY(CallStackEntry cse("LockedRepartitionRight")) LockedView( A0, AL ); LockedPartitionRight( AR, A1, A2, A1Width ); }
inline void LockedRepartitionLeft ( const M& AL, const M& AR, M& A0, M& A1, M& A2, Int A1Width=Blocksize() ) { DEBUG_ONLY(CallStackEntry cse("LockedRepartitionLeft")) LockedPartitionLeft( AL, A0, A1, A1Width ); LockedView( A2, AR ); }
inline void SlideLockedPartitionRight ( DM& AL, DM& AR, const DM& A0, const DM& A1, const DM& A2 ) { DEBUG_ONLY(CallStackEntry cse("SlideLockedPartitionRight")) LockedView1x2( AL, A0, A1 ); LockedView( AR, A2 ); }
inline void LockedPartitionDown ( const DM& A, DM& AT, DM& AB, Int heightAT ) { #ifndef RELEASE PushCallStack("LockedPartitionDown [DistMatrix]"); if( heightAT < 0 ) throw std::logic_error("Height of top partition must be non-negative"); #endif heightAT = std::min(heightAT,A.Height()); const Int heightAB = A.Height()-heightAT; LockedView( AT, A, 0, 0, heightAT, A.Width() ); LockedView( AB, A, heightAT, 0, heightAB, A.Width() ); #ifndef RELEASE PopCallStack(); #endif }
inline void SlideLockedPartitionLeft ( M& AL, M& AR, const M& A0, const M& A1, const M& A2 ) { DEBUG_ONLY(CallStackEntry cse("SlideLockedPartitionLeft")) LockedView( AL, A0 ); LockedView1x2( AR, A1, A2 ); }
inline void SlideLockedPartitionUp ( DM& AT, const DM& A0, const DM& A1, DM& AB, const DM& A2 ) { DEBUG_ONLY(CallStackEntry cse("SlideLockedPartitionUp")) LockedView( AT, A0 ); LockedView2x1( AB, A1, A2 ); }
inline void SlideLockedPartitionDown ( M& AT, const M& A0, const M& A1, M& AB, const M& A2 ) { DEBUG_ONLY(CallStackEntry cse("SlideLockedPartitionDown")) LockedView2x1( AT, A0, A1 ); LockedView( AB, A2 ); }
inline void LockedPartitionUp ( const M& A, M& AT, M& AB, Int heightAB ) { #ifndef RELEASE PushCallStack("LockedPartitionUp [Matrix]"); if( heightAB < 0 ) throw std::logic_error ("Height of bottom partition must be non-negative"); #endif heightAB = std::min(heightAB,A.Height()); const Int heightAT = A.Height()-heightAB; LockedView( AT, A, 0, 0, heightAT, A.Width() ); LockedView( AB, A, heightAT, 0, heightAB, A.Width() ); #ifndef RELEASE PopCallStack(); #endif }
inline void LockedRepartitionDown ( const M& AT, M& A0, M& A1, const M& AB, M& A2, Int A1Height=Blocksize() ) { DEBUG_ONLY(CallStackEntry cse("LockedRepartitionDown")) LockedView( A0, AT ); LockedPartitionDown( AB, A1, A2, A1Height ); }
inline void LockedRepartitionUp ( const DM& AT, DM& A0, DM& A1, const DM& AB, DM& A2, Int A1Height=Blocksize() ) { DEBUG_ONLY(CallStackEntry cse("LockedRepartitionUp")) LockedPartitionUp( AT, A0, A1, A1Height ); LockedView( A2, AB ); }
inline void LockedRepartitionRight ( const DM& AL, const DM& AR, DM& A0, DM& A1, DM& A2, Int A1Width ) { #ifndef RELEASE CallStackEntry cse("LockedRepartitionRight [DistMatrix]"); #endif LockedView( A0, AL ); LockedPartitionRight( AR, A1, A2, A1Width ); }
inline void LockedRepartitionLeft ( const M& AL, const M& AR, M& A0, M& A1, M& A2, Int A1Width ) { #ifndef RELEASE CallStackEntry cse("LockedRepartitionLeft [Matrix]"); #endif LockedPartitionLeft( AL, A0, A1, A1Width ); LockedView( A2, AR ); }
inline void LockedRepartitionUp ( const DM& AT, DM& A0, DM& A1, const DM& AB, DM& A2, Int A1Height ) { #ifndef RELEASE CallStackEntry cse("LockedRepartitionUp [DistMatrix]"); #endif LockedPartitionUp( AT, A0, A1, A1Height ); LockedView( A2, AB ); }
inline void LockedRepartitionDown ( const M& AT, M& A0, M& A1, const M& AB, M& A2, Int A1Height ) { #ifndef RELEASE CallStackEntry cse("LockedRepartitionDown [Matrix]"); #endif LockedView( A0, AT ); LockedPartitionDown( AB, A1, A2, A1Height ); }
inline void SlideLockedPartitionDownDiagonal ( DM& ATL, DM& ATR, const DM& A00, const DM& A01, const DM& A02, const DM& A10, const DM& A11, const DM& A12, DM& ABL, DM& ABR, const DM& A20, const DM& A21, const DM& A22 ) { DEBUG_ONLY(CallStackEntry cse("SlideLockedPartitionDownDiagonal")) LockedView2x2( ATL, A00, A01, A10, A11 ); LockedView2x1( ATR, A02, A12 ); LockedView1x2( ABL, A20, A21 ); LockedView( ABR, A22 ); }
inline void LockedRepartitionDownDiagonal ( const M& ATL, const M& ATR, M& A00, M& A01, M& A02, M& A10, M& A11, M& A12, const M& ABL, const M& ABR, M& A20, M& A21, M& A22, Int bsize=Blocksize() ) { DEBUG_ONLY(CallStackEntry cse("LockedRepartitionDownDiagonal")) LockedView( A00, ATL ); LockedPartitionDownDiagonal( ABR, A11, A12, A21, A22, bsize ); LockedPartitionDown( ABL, A10, A20, A11.Height() ); LockedPartitionRight( ATR, A01, A02, A11.Width() ); }
inline void LockedPartitionDownLeftDiagonal ( const DM& A, DM& ATL, DM& ATR, DM& ABL, DM& ABR, Int diagATL ) { #ifndef RELEASE PushCallStack("LockedPartitionDownLeftDiagonal [DistMatrix]"); if( diagATL < 0 ) throw std::logic_error("Top-left size must be non-negative"); #endif const Int minDim = std::min(A.Height(),A.Width()); diagATL = std::min(diagATL,minDim); const Int heightABR = A.Height()-diagATL; const Int widthABR = A.Width()-diagATL; LockedView( ATL, A, 0, 0, diagATL, diagATL ); LockedView( ATR, A, 0, diagATL, diagATL, widthABR ); LockedView( ABL, A, diagATL, 0, heightABR, diagATL ); LockedView( ABR, A, diagATL, diagATL, heightABR, widthABR ); #ifndef RELEASE PopCallStack(); #endif }
inline void LockedPartitionUpRightDiagonal ( const DM& A, DM& ATL, DM& ATR, DM& ABL, DM& ABR, Int diagABR ) { #ifndef RELEASE PushCallStack("LockedPartitionUpRightDiagonal [DistMatrix]"); if( diagABR < 0 ) throw std::logic_error("Bottom-right size must be non-negative"); #endif const Int minDim = std::min(A.Height(),A.Width()); diagABR = std::min(diagABR,minDim); const Int remHeight = A.Height()-diagABR; const Int remWidth = A.Width()-diagABR; LockedView( ATL, A, 0, 0, remHeight, remWidth ); LockedView( ATR, A, 0, remWidth, remHeight, diagABR ); LockedView( ABL, A, remHeight, 0, diagABR, remWidth ); LockedView( ABR, A, remHeight, remWidth, diagABR, diagABR ); #ifndef RELEASE PopCallStack(); #endif }
inline void LockedPartitionDownRightDiagonal ( const M& A, M& ATL, M& ATR, M& ABL, M& ABR, Int diagATL ) { #ifndef RELEASE PushCallStack("LockedPartitionDownRightDiagonal [Matrix]"); if( diagATL < 0 ) throw std::logic_error("Top-left size must be non-negative"); #endif const Int minDim = std::min( A.Height(), A.Width() ); diagATL = std::min(diagATL,minDim); const Int sizeABR = minDim-diagATL; const Int remHeight = A.Height()-sizeABR; const Int remWidth = A.Width()-sizeABR; LockedView( ATL, A, 0, 0, remHeight, remWidth ); LockedView( ATR, A, 0, remWidth, remHeight, sizeABR ); LockedView( ABL, A, remHeight, 0, sizeABR, remWidth ); LockedView( ABR, A, remHeight, remWidth, sizeABR, sizeABR ); #ifndef RELEASE PopCallStack(); #endif }
inline void LockedRepartitionUpDiagonal ( const M& ATL, const M& ATR, M& A00, M& A01, M& A02, M& A10, M& A11, M& A12, const M& ABL, const M& ABR, M& A20, M& A21, M& A22, Int bsize=Blocksize() ) { DEBUG_ONLY(CallStackEntry cse("LockedRepartitionUpDiagonal")) LockedPartitionUpOffsetDiagonal ( ATL.Width()-ATL.Height(), ATL, A00, A01, A10, A11, bsize ); LockedPartitionUp( ATR, A02, A12, A11.Height() ); LockedPartitionLeft( ABL, A20, A21, A11.Width() ); LockedView( A22, ABR ); }
inline void LockedRepartitionDownDiagonal ( const DM& ATL, const DM& ATR, DM& A00, DM& A01, DM& A02, DM& A10, DM& A11, DM& A12, const DM& ABL, const DM& ABR, DM& A20, DM& A21, DM& A22, Int bsize ) { #ifndef RELEASE CallStackEntry cse("LockedRepartitionDownDiagonal [DistMatrix]"); #endif LockedView( A00, ATL ); LockedPartitionDownDiagonal( ABR, A11, A12, A21, A22, bsize ); LockedPartitionDown( ABL, A10, A20, A11.Height() ); LockedPartitionRight( ATR, A01, A02, A11.Width() ); }
inline void LockedRepartitionUpDiagonal ( const M& ATL, const M& ATR, M& A00, M& A01, M& A02, M& A10, M& A11, M& A12, const M& ABL, const M& ABR, M& A20, M& A21, M& A22, Int bsize ) { #ifndef RELEASE CallStackEntry cse("LockedRepartitionUpDiagonal [Matrix]"); #endif LockedPartitionUpOffsetDiagonal ( ATL.Width()-ATL.Height(), ATL, A00, A01, A10, A11, bsize ); LockedPartitionUp( ATR, A02, A12, A11.Height() ); LockedPartitionLeft( ABL, A20, A21, A11.Width() ); LockedView( A22, ABR ); }
void ReshapeIntoGrid ( Int realSize, Int imagSize, const ElementalMatrix<T>& x, ElementalMatrix<T>& X ) { X.SetGrid( x.Grid() ); X.Resize( imagSize, realSize ); auto xSub = unique_ptr<ElementalMatrix<T>> ( x.Construct(x.Grid(),x.Root()) ); auto XSub = unique_ptr<ElementalMatrix<T>> ( X.Construct(X.Grid(),X.Root()) ); for( Int j=0; j<realSize; ++j ) { View( *XSub, X, IR(0,imagSize), IR(j) ); LockedView( *xSub, x, IR(j*imagSize,(j+1)*imagSize), ALL ); Copy( *xSub, *XSub ); } }
inline void TrsvUN( UnitOrNonUnit diag, const DistMatrix<F>& U, DistMatrix<F>& x ) { #ifndef RELEASE PushCallStack("internal::TrsvUN"); if( U.Grid() != x.Grid() ) throw std::logic_error("{U,x} must be distributed over the same grid"); if( U.Height() != U.Width() ) throw std::logic_error("U must be square"); if( x.Width() != 1 && x.Height() != 1 ) throw std::logic_error("x must be a vector"); const int xLength = ( x.Width() == 1 ? x.Height() : x.Width() ); if( U.Width() != xLength ) throw std::logic_error("Nonconformal TrsvUN"); #endif const Grid& g = U.Grid(); if( x.Width() == 1 ) { // Matrix views DistMatrix<F> U01(g), U11(g); DistMatrix<F> xT(g), x0(g), xB(g), x1(g), x2(g); // Temporary distributions DistMatrix<F,STAR,STAR> U11_STAR_STAR(g); DistMatrix<F,STAR,STAR> x1_STAR_STAR(g); DistMatrix<F,MR, STAR> x1_MR_STAR(g); DistMatrix<F,MC, STAR> z_MC_STAR(g); // Views of z[MC,* ], which will store updates to x DistMatrix<F,MC,STAR> z0_MC_STAR(g), z1_MC_STAR(g); z_MC_STAR.AlignWith( U ); Zeros( x.Height(), 1, z_MC_STAR ); // Start the algorithm PartitionUp ( x, xT, xB, 0 ); while( xT.Height() > 0 ) { RepartitionUp ( xT, x0, x1, /**/ /**/ xB, x2 ); const int n0 = x0.Height(); const int n1 = x1.Height(); LockedView( U01, U, 0, n0, n0, n1 ); LockedView( U11, U, n0, n0, n1, n1 ); View( z0_MC_STAR, z_MC_STAR, 0, 0, n0, 1 ); View( z1_MC_STAR, z_MC_STAR, n0, 0, n1, 1 ); x1_MR_STAR.AlignWith( U01 ); //----------------------------------------------------------------// if( x2.Height() != 0 ) x1.SumScatterUpdate( F(1), z1_MC_STAR ); x1_STAR_STAR = x1; U11_STAR_STAR = U11; Trsv ( UPPER, NORMAL, diag, U11_STAR_STAR.LockedLocalMatrix(), x1_STAR_STAR.LocalMatrix() ); x1 = x1_STAR_STAR; x1_MR_STAR = x1_STAR_STAR; Gemv ( NORMAL, F(-1), U01.LockedLocalMatrix(), x1_MR_STAR.LockedLocalMatrix(), F(1), z0_MC_STAR.LocalMatrix() ); //----------------------------------------------------------------// x1_MR_STAR.FreeAlignments(); SlidePartitionUp ( xT, x0, /**/ /**/ x1, xB, x2 ); } } else { // Matrix views DistMatrix<F> U01(g), U11(g); DistMatrix<F> xL(g), xR(g), x0(g), x1(g), x2(g); // Temporary distributions DistMatrix<F,STAR,STAR> U11_STAR_STAR(g); DistMatrix<F,STAR,STAR> x1_STAR_STAR(g); DistMatrix<F,STAR,MR > x1_STAR_MR(g); DistMatrix<F,MC, MR > z1(g); DistMatrix<F,MR, MC > z1_MR_MC(g); DistMatrix<F,STAR,MC > z_STAR_MC(g); // Views of z[* ,MC] DistMatrix<F,STAR,MC> z0_STAR_MC(g), z1_STAR_MC(g); z_STAR_MC.AlignWith( U ); Zeros( 1, x.Width(), z_STAR_MC ); // Start the algorithm PartitionLeft( x, xL, xR, 0 ); while( xL.Width() > 0 ) { RepartitionLeft ( xL, /**/ xR, x0, x1, /**/ x2 ); const int n0 = x0.Width(); const int n1 = x1.Width(); LockedView( U01, U, 0, n0, n0, n1 ); LockedView( U11, U, n0, n0, n1, n1 ); View( z0_STAR_MC, z_STAR_MC, 0, 0, 1, n0 ); View( z1_STAR_MC, z_STAR_MC, 0, n0, 1, n1 ); x1_STAR_MR.AlignWith( U01 ); z1.AlignWith( x1 ); //----------------------------------------------------------------// if( x2.Width() != 0 ) { z1_MR_MC.SumScatterFrom( z1_STAR_MC ); z1 = z1_MR_MC; Axpy( F(1), z1, x1 ); } x1_STAR_STAR = x1; U11_STAR_STAR = U11; Trsv ( UPPER, NORMAL, diag, U11_STAR_STAR.LockedLocalMatrix(), x1_STAR_STAR.LocalMatrix() ); x1 = x1_STAR_STAR; x1_STAR_MR = x1_STAR_STAR; Gemv ( NORMAL, F(-1), U01.LockedLocalMatrix(), x1_STAR_MR.LockedLocalMatrix(), F(1), z0_STAR_MC.LocalMatrix() ); //----------------------------------------------------------------// x1_STAR_MR.FreeAlignments(); z1.FreeAlignments(); SlidePartitionLeft ( xL, /**/ xR, x0, /**/ x1, x2 ); } } #ifndef RELEASE PopCallStack(); #endif }
inline Matrix<T> LockedView( const Matrix<T>& B ) { Matrix<T> A; LockedView( A, B ); return A; }
inline void RLHF ( Conjugation conjugation, int offset, const DistMatrix<Complex<R> >& H, const DistMatrix<Complex<R>,MD,STAR>& t, DistMatrix<Complex<R> >& A ) { #ifndef RELEASE PushCallStack("apply_packed_reflectors::RLHF"); if( H.Grid() != t.Grid() || t.Grid() != A.Grid() ) throw std::logic_error ("{H,t,A} must be distributed over the same grid"); if( offset > 0 || offset < -H.Width() ) throw std::logic_error("Transforms out of bounds"); if( H.Width() != A.Width() ) throw std::logic_error ("Width of transforms must equal width of target matrix"); if( t.Height() != H.DiagonalLength( offset ) ) throw std::logic_error("t must be the same length as H's offset diag"); if( !t.AlignedWithDiagonal( H, offset ) ) throw std::logic_error("t must be aligned with H's 'offset' diagonal"); #endif typedef Complex<R> C; const Grid& g = H.Grid(); DistMatrix<C> HTL(g), HTR(g), H00(g), H01(g), H02(g), HPan(g), HPanCopy(g), HBL(g), HBR(g), H10(g), H11(g), H12(g), H20(g), H21(g), H22(g); DistMatrix<C> ALeft(g); DistMatrix<C,MD,STAR> tT(g), t0(g), tB(g), t1(g), t2(g); DistMatrix<C,STAR,VR > HPan_STAR_VR(g); DistMatrix<C,STAR,MR > HPan_STAR_MR(g); DistMatrix<C,STAR,STAR> t1_STAR_STAR(g); DistMatrix<C,STAR,STAR> SInv_STAR_STAR(g); DistMatrix<C,STAR,MC > ZAdj_STAR_MC(g); DistMatrix<C,STAR,VC > ZAdj_STAR_VC(g); LockedPartitionDownDiagonal ( H, HTL, HTR, HBL, HBR, 0 ); LockedPartitionDown ( t, tT, tB, 0 ); while( HTL.Height() < H.Height() && HTL.Width() < H.Width() ) { LockedRepartitionDownDiagonal ( HTL, /**/ HTR, H00, /**/ H01, H02, /*************/ /******************/ /**/ H10, /**/ H11, H12, HBL, /**/ HBR, H20, /**/ H21, H22 ); const int HPanWidth = H10.Width() + H11.Width(); const int HPanOffset = std::min( H11.Height(), std::max(-offset-H00.Height(),0) ); const int HPanHeight = H11.Height()-HPanOffset; LockedView ( HPan, H, H00.Height()+HPanOffset, 0, HPanHeight, HPanWidth ); LockedRepartitionDown ( tT, t0, /**/ /**/ t1, tB, t2, HPanHeight ); View( ALeft, A, 0, 0, A.Height(), HPanWidth ); HPan_STAR_MR.AlignWith( ALeft ); ZAdj_STAR_MC.AlignWith( ALeft ); ZAdj_STAR_VC.AlignWith( ALeft ); Zeros( HPan.Height(), ALeft.Height(), ZAdj_STAR_MC ); Zeros( HPan.Height(), HPan.Height(), SInv_STAR_STAR ); //--------------------------------------------------------------------// HPanCopy = HPan; MakeTrapezoidal( RIGHT, LOWER, offset, HPanCopy ); SetDiagonal( RIGHT, offset, HPanCopy, C(1) ); HPan_STAR_VR = HPanCopy; Herk ( UPPER, NORMAL, C(1), HPan_STAR_VR.LockedMatrix(), C(0), SInv_STAR_STAR.Matrix() ); SInv_STAR_STAR.SumOverGrid(); t1_STAR_STAR = t1; FixDiagonal( conjugation, t1_STAR_STAR, SInv_STAR_STAR ); HPan_STAR_MR = HPan_STAR_VR; LocalGemm ( NORMAL, ADJOINT, C(1), HPan_STAR_MR, ALeft, C(0), ZAdj_STAR_MC ); ZAdj_STAR_VC.SumScatterFrom( ZAdj_STAR_MC ); LocalTrsm ( LEFT, UPPER, ADJOINT, NON_UNIT, C(1), SInv_STAR_STAR, ZAdj_STAR_VC ); ZAdj_STAR_MC = ZAdj_STAR_VC; LocalGemm ( ADJOINT, NORMAL, C(-1), ZAdj_STAR_MC, HPan_STAR_MR, C(1), ALeft ); //--------------------------------------------------------------------// HPan_STAR_MR.FreeAlignments(); ZAdj_STAR_MC.FreeAlignments(); ZAdj_STAR_VC.FreeAlignments(); SlideLockedPartitionDownDiagonal ( HTL, /**/ HTR, H00, H01, /**/ H02, /**/ H10, H11, /**/ H12, /*************/ /******************/ HBL, /**/ HBR, H20, H21, /**/ H22 ); SlideLockedPartitionDown ( tT, t0, t1, /**/ /**/ tB, t2 ); } #ifndef RELEASE PopCallStack(); #endif }
inline void RLHF ( Conjugation conjugation, int offset, const Matrix<Complex<R> >& H, const Matrix<Complex<R> >& t, Matrix<Complex<R> >& A ) { #ifndef RELEASE PushCallStack("apply_packed_reflectors::RLHF"); if( offset > 0 || offset < -H.Width() ) throw std::logic_error("Transforms out of bounds"); if( H.Width() != A.Width() ) throw std::logic_error ("Width of transforms must equal width of target matrix"); if( t.Height() != H.DiagonalLength( offset ) ) throw std::logic_error("t must be the same length as H's offset diag"); #endif typedef Complex<R> C; Matrix<C> HTL, HTR, H00, H01, H02, HPan, HPanCopy, HBL, HBR, H10, H11, H12, H20, H21, H22; Matrix<C> ALeft; Matrix<C> tT, t0, tB, t1, t2; Matrix<C> SInv, Z; LockedPartitionDownDiagonal ( H, HTL, HTR, HBL, HBR, 0 ); LockedPartitionDown ( t, tT, tB, 0 ); while( HTL.Height() < H.Height() && HTL.Width() < H.Width() ) { LockedRepartitionDownDiagonal ( HTL, /**/ HTR, H00, /**/ H01, H02, /*************/ /******************/ /**/ H10, /**/ H11, H12, HBL, /**/ HBR, H20, /**/ H21, H22 ); const int HPanWidth = H10.Width() + H11.Width(); const int HPanOffset = std::min( H11.Height(), std::max(-offset-H00.Height(),0) ); const int HPanHeight = H11.Height()-HPanOffset; LockedView ( HPan, H, H00.Height()+HPanOffset, 0, HPanHeight, HPanWidth ); LockedRepartitionDown ( tT, t0, /**/ /**/ t1, tB, t2, HPanHeight ); View( ALeft, A, 0, 0, A.Height(), HPanWidth ); Zeros( ALeft.Height(), HPan.Height(), Z ); Zeros( HPan.Height(), HPan.Height(), SInv ); //--------------------------------------------------------------------// HPanCopy = HPan; MakeTrapezoidal( RIGHT, LOWER, offset, HPanCopy ); SetDiagonal( RIGHT, offset, HPanCopy, C(1) ); Herk( UPPER, NORMAL, C(1), HPanCopy, C(0), SInv ); FixDiagonal( conjugation, t1, SInv ); Gemm( NORMAL, ADJOINT, C(1), ALeft, HPanCopy, C(0), Z ); Trsm( RIGHT, UPPER, NORMAL, NON_UNIT, C(1), SInv, Z ); Gemm( NORMAL, NORMAL, C(-1), Z, HPanCopy, C(1), ALeft ); //--------------------------------------------------------------------// SlideLockedPartitionDownDiagonal ( HTL, /**/ HTR, H00, H01, /**/ H02, /**/ H10, H11, /**/ H12, /*************/ /******************/ HBL, /**/ HBR, H20, H21, /**/ H22 ); SlideLockedPartitionDown ( tT, t0, t1, /**/ /**/ tB, t2 ); } #ifndef RELEASE PopCallStack(); #endif }