void L( Matrix<F>& A, Matrix<F>& t ) { #ifndef RELEASE CallStackEntry entry("hermitian_tridiag::L"); if( A.Height() != A.Width() ) LogicError("A must be square"); #endif typedef BASE(F) R; const Int tHeight = Max(A.Height()-1,0); t.ResizeTo( tHeight, 1 ); // Matrix views Matrix<F> ATL, ATR, A00, a01, A02, alpha21T, ABL, ABR, a10, alpha11, a12, a21B, A20, a21, A22; // Temporary matrices Matrix<F> w21; PartitionDownDiagonal ( A, ATL, ATR, ABL, ABR, 0 ); while( ATL.Height()+1 < A.Height() ) { RepartitionDownDiagonal ( ATL, /**/ ATR, A00, /**/ a01, A02, /*************/ /**********************/ /**/ a10, /**/ alpha11, a12, ABL, /**/ ABR, A20, /**/ a21, A22, 1 ); PartitionDown ( a21, alpha21T, a21B, 1 ); //--------------------------------------------------------------------// const F tau = Reflector( alpha21T, a21B ); const R epsilon1 = alpha21T.GetRealPart(0,0); t.Set(A00.Height(),0,tau); alpha21T.Set(0,0,F(1)); Zeros( w21, a21.Height(), 1 ); Hemv( LOWER, tau, A22, a21, F(0), w21 ); const F alpha = -tau*Dot( w21, a21 )/F(2); Axpy( alpha, a21, w21 ); Her2( LOWER, F(-1), a21, w21, A22 ); alpha21T.Set(0,0,epsilon1); //--------------------------------------------------------------------// SlidePartitionDownDiagonal ( ATL, /**/ ATR, A00, a01, /**/ A02, /**/ a10, alpha11, /**/ a12, /*************/ /**********************/ ABL, /**/ ABR, A20, a21, /**/ A22 ); } }
inline void HermitianTridiagU ( Matrix<Complex<R> >& A, Matrix<Complex<R> >& t ) { #ifndef RELEASE PushCallStack("HermitianTridiagU"); #endif const int tHeight = std::max(A.Height()-1,0); #ifndef RELEASE if( A.Height() != A.Width() ) throw std::logic_error("A must be square"); if( t.Viewing() && (t.Height() != tHeight || t.Width() != 1) ) throw std::logic_error("t is of the wrong size"); #endif typedef Complex<R> C; if( !t.Viewing() ) t.ResizeTo( tHeight, 1 ); // Matrix views Matrix<C> ATL, ATR, A00, a01, A02, a01T, ABL, ABR, a10, alpha11, a12, alpha01B, A20, a21, A22; // Temporary matrices Matrix<C> w01; PushBlocksizeStack( 1 ); PartitionUpDiagonal ( A, ATL, ATR, ABL, ABR, 0 ); while( ABR.Height()+1 < A.Height() ) { RepartitionUpDiagonal ( ATL, /**/ ATR, A00, a01, /**/ A02, /**/ a10, alpha11, /**/ a12, /*************/ /**********************/ ABL, /**/ ABR, A20, a21, /**/ A22 ); PartitionUp ( a01, a01T, alpha01B, 1 ); w01.ResizeTo( a01.Height(), 1 ); //--------------------------------------------------------------------// const C tau = Reflector( alpha01B, a01T ); const R epsilon1 = alpha01B.GetRealPart(0,0); t.Set(t.Height()-1-A22.Height(),0,tau); alpha01B.Set(0,0,C(1)); Hemv( UPPER, tau, A00, a01, C(0), w01 ); const C alpha = -tau*Dot( w01, a01 )/C(2); Axpy( alpha, a01, w01 ); Her2( UPPER, C(-1), a01, w01, A00 ); alpha01B.Set(0,0,epsilon1); //--------------------------------------------------------------------// SlidePartitionUpDiagonal ( ATL, /**/ ATR, A00, /**/ a01, A02, /*************/ /**********************/ /**/ a10, /**/ alpha11, a12, ABL, /**/ ABR, A20, /**/ a21, A22 ); } PopBlocksizeStack(); #ifndef RELEASE PopCallStack(); #endif }