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<R>& A ) { #ifndef RELEASE PushCallStack("HermitianTridiagU"); if( A.Height() != A.Width() ) throw std::logic_error( "A must be square." ); #endif // Matrix views Matrix<R> ATL, ATR, A00, a01, A02, a01T, ABL, ABR, a10, alpha11, a12, alpha01B, A20, a21, A22; // Temporary matrices Matrix<R> 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 R tau = Reflector( alpha01B, a01T ); const R epsilon1 = alpha01B.Get(0,0); alpha01B.Set(0,0,R(1)); Symv( UPPER, tau, A00, a01, R(0), w01 ); const R alpha = -tau*Dot( w01, a01 )/R(2); Axpy( alpha, a01, w01 ); Syr2( UPPER, R(-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 }
inline void PanelQR( Matrix<Real>& A ) { #ifndef RELEASE PushCallStack("internal::PanelQR"); #endif Matrix<Real> ATL, ATR, A00, a01, A02, aLeftCol, ARightPan, ABL, ABR, a10, alpha11, a12, A20, a21, A22; Matrix<Real> z; PushBlocksizeStack( 1 ); PartitionDownLeftDiagonal ( A, ATL, ATR, ABL, ABR, 0 ); while( ATL.Height() < A.Height() && ATL.Width() < A.Width() ) { RepartitionDownDiagonal ( ATL, /**/ ATR, A00, /**/ a01, A02, /*************/ /**********************/ /**/ a10, /**/ alpha11, a12, ABL, /**/ ABR, A20, /**/ a21, A22 ); aLeftCol.View2x1( alpha11, a21 ); ARightPan.View2x1( a12, A22 ); Zeros( ARightPan.Width(), 1, z ); //--------------------------------------------------------------------// const Real tau = Reflector( alpha11, a21 ); const Real alpha = alpha11.Get(0,0); alpha11.Set(0,0,1); Gemv( TRANSPOSE, Real(1), ARightPan, aLeftCol, Real(0), z ); Ger( -tau, aLeftCol, z, ARightPan ); alpha11.Set(0,0,alpha); //--------------------------------------------------------------------// SlidePartitionDownDiagonal ( ATL, /**/ ATR, A00, a01, /**/ A02, /**/ a10, alpha11, /**/ a12, /*************/ /**********************/ ABL, /**/ ABR, A20, a21, /**/ A22 ); } PopBlocksizeStack(); #ifndef RELEASE PopCallStack(); #endif }
inline void PanelLQ( Matrix<Real>& A ) { #ifndef RELEASE PushCallStack("internal::PanelLQ"); #endif Matrix<Real> ATL, ATR, A00, a01, A02, aTopRow, ABottomPan, ABL, ABR, a10, alpha11, a12, A20, a21, A22; Matrix<Real> z; PushBlocksizeStack( 1 ); PartitionDownLeftDiagonal ( A, ATL, ATR, ABL, ABR, 0 ); while( ATL.Height() < A.Height() && ATL.Width() < A.Width() ) { RepartitionDownDiagonal ( ATL, /**/ ATR, A00, /**/ a01, A02, /*************/ /**********************/ /**/ a10, /**/ alpha11, a12, ABL, /**/ ABR, A20, /**/ a21, A22 ); aTopRow.View1x2( alpha11, a12 ); ABottomPan.View1x2( a21, A22 ); Zeros( ABottomPan.Height(), 1, z ); //--------------------------------------------------------------------// const Real tau = Reflector( alpha11, a12 ); const Real alpha = alpha11.Get(0,0); alpha11.Set(0,0,1); Gemv( NORMAL, Real(1), ABottomPan, aTopRow, Real(0), z ); Ger( -tau, z, aTopRow, ABottomPan ); alpha11.Set(0,0,alpha); //--------------------------------------------------------------------// SlidePartitionDownDiagonal ( ATL, /**/ ATR, A00, a01, /**/ A02, /**/ a10, alpha11, /**/ a12, /*************/ /**********************/ ABL, /**/ ABR, A20, a21, /**/ A22 ); } PopBlocksizeStack(); #ifndef RELEASE PopCallStack(); #endif }
void CreateScene(Scene& scene) { scene.Clear(); scene.EnableLighting = false; scene.EnableFlatShading = false; ReflTexture* refl = new ReflTexture(); scene.SetAmbient(Color(0.4, 0.4, 0.4)); scene.AddLight(Point3D(0,-100,80), Color(0.8, 0.8, 0.8)); scene.SetTexture(NULL, NULL, refl); scene.modeling.Push(); scene.SetColor(HSVColor(0.66, 1.0, 0.9), HSVColor(0.0, 0.0, 1.5), 120); Reflector(scene, 12*4, 12*4); scene.modeling.Pop(); }
inline void PanelHouseholder( Matrix<F>& A, Matrix<F>& t ) { #ifndef RELEASE CallStackEntry entry("lq::PanelHouseholder"); if( t.Height() != Min(A.Height(),A.Width()) || t.Width() != 1 ) LogicError ("t must be a vector of height equal to the minimum dimension of A"); #endif Matrix<F> ATL, ATR, A00, a01, A02, aTopRow, ABottomPan, ABL, ABR, a10, alpha11, a12, A20, a21, A22; Matrix<F> tT, t0, tB, tau1, t2; Matrix<F> z, aTopRowConj; PartitionDownDiagonal ( A, ATL, ATR, ABL, ABR, 0 ); PartitionDown ( t, tT, tB, 0 ); while( ATL.Height() < A.Height() && ATL.Width() < A.Width() ) { RepartitionDownDiagonal ( ATL, /**/ ATR, A00, /**/ a01, A02, /*************/ /**********************/ /**/ a10, /**/ alpha11, a12, ABL, /**/ ABR, A20, /**/ a21, A22, 1 ); RepartitionDown ( tT, t0, /**/ /****/ tau1, tB, t2, 1 ); View1x2( aTopRow, alpha11, a12 ); View1x2( ABottomPan, a21, A22 ); //--------------------------------------------------------------------// // Compute the Householder reflector const F tau = Reflector( alpha11, a12 ); tau1.Set( 0, 0, tau ); // Apply the Householder reflector const F alpha = alpha11.Get(0,0); alpha11.Set(0,0,1); Conjugate( aTopRow, aTopRowConj ); Zeros( z, ABottomPan.Height(), 1 ); Gemv( NORMAL, F(1), ABottomPan, aTopRowConj, F(0), z ); Ger( -Conj(tau), z, aTopRowConj, ABottomPan ); alpha11.Set(0,0,alpha); //--------------------------------------------------------------------// SlidePartitionDown ( tT, t0, tau1, /**/ /****/ tB, t2 ); SlidePartitionDownDiagonal ( ATL, /**/ ATR, A00, a01, /**/ A02, /**/ a10, alpha11, /**/ a12, /*************/ /**********************/ ABL, /**/ ABR, A20, a21, /**/ A22 ); } }
inline void PanelHouseholder( DistMatrix<F>& A, DistMatrix<F,MD,STAR>& t ) { #ifndef RELEASE CallStackEntry entry("lq::PanelHouseholder"); if( A.Grid() != t.Grid() ) LogicError("{A,t} must be distributed over the same grid"); if( t.Height() != Min(A.Height(),A.Width()) || t.Width() != 1 ) LogicError ("t must be a vector of height equal to the minimum dimension of A"); if( !t.AlignedWithDiagonal( A, 0 ) ) LogicError("t must be aligned with A's main diagonal"); #endif const Grid& g = A.Grid(); // Matrix views DistMatrix<F> ATL(g), ATR(g), A00(g), a01(g), A02(g), aTopRow(g), ABottomPan(g), ABL(g), ABR(g), a10(g), alpha11(g), a12(g), A20(g), a21(g), A22(g); DistMatrix<F,MD,STAR> tT(g), t0(g), tB(g), tau1(g), t2(g); // Temporary distributions DistMatrix<F> aTopRowConj(g); DistMatrix<F,STAR,MR > aTopRowConj_STAR_MR(g); DistMatrix<F,MC, STAR> z_MC_STAR(g); PartitionDownDiagonal ( A, ATL, ATR, ABL, ABR, 0 ); PartitionDown ( t, tT, tB, 0 ); while( ATL.Height() < A.Height() && ATL.Width() < A.Width() ) { RepartitionDownDiagonal ( ATL, /**/ ATR, A00, /**/ a01, A02, /*************/ /**********************/ /**/ a10, /**/ alpha11, a12, ABL, /**/ ABR, A20, /**/ a21, A22, 1 ); RepartitionDown ( tT, t0, /**/ /****/ tau1, tB, t2, 1 ); View1x2( aTopRow, alpha11, a12 ); View1x2( ABottomPan, a21, A22 ); aTopRowConj_STAR_MR.AlignWith( ABottomPan ); z_MC_STAR.AlignWith( ABottomPan ); //--------------------------------------------------------------------// // Compute the Householder reflector const F tau = Reflector( alpha11, a12 ); tau1.Set( 0, 0, tau ); // Apply the Householder reflector const bool myDiagonalEntry = ( g.Row() == alpha11.ColAlignment() && g.Col() == alpha11.RowAlignment() ); F alpha = 0; if( myDiagonalEntry ) { alpha = alpha11.GetLocal(0,0); alpha11.SetLocal(0,0,1); } Conjugate( aTopRow, aTopRowConj ); aTopRowConj_STAR_MR = aTopRowConj; Zeros( z_MC_STAR, ABottomPan.Height(), 1 ); LocalGemv ( NORMAL, F(1), ABottomPan, aTopRowConj_STAR_MR, F(0), z_MC_STAR ); z_MC_STAR.SumOverRow(); Ger ( -Conj(tau), z_MC_STAR.LockedMatrix(), aTopRowConj_STAR_MR.LockedMatrix(), ABottomPan.Matrix() ); if( myDiagonalEntry ) alpha11.SetLocal(0,0,alpha); //--------------------------------------------------------------------// SlidePartitionDown ( tT, t0, tau1, /**/ /****/ tB, t2 ); SlidePartitionDownDiagonal ( ATL, /**/ ATR, A00, a01, /**/ A02, /**/ a10, alpha11, /**/ a12, /*************/ /**********************/ ABL, /**/ ABR, A20, a21, /**/ A22 ); } }
inline void UnblockedBidiagU ( DistMatrix<Complex<R> >& A, DistMatrix<Complex<R>,MD,STAR>& tP, DistMatrix<Complex<R>,MD,STAR>& tQ ) { #ifndef RELEASE PushCallStack("BidiagU"); #endif const int tPHeight = std::max(A.Width()-1,0); const int tQHeight = A.Width(); #ifndef RELEASE if( A.Grid() != tP.Grid() || tP.Grid() != tQ.Grid() ) throw std::logic_error("Process grids do not match"); if( A.Height() < A.Width() ) throw std::logic_error("A must be at least as tall as it is wide"); if( tP.Viewing() && (tP.Height() != tPHeight || tP.Width() != 1) ) throw std::logic_error("tP is the wrong height"); if( tQ.Viewing() && (tQ.Height() != tQHeight || tQ.Width() != 1) ) throw std::logic_error("tQ is the wrong height"); #endif typedef Complex<R> C; const Grid& g = A.Grid(); if( !tP.Viewing() ) tP.ResizeTo( tPHeight, 1 ); if( !tQ.Viewing() ) tQ.ResizeTo( tQHeight, 1 ); // Matrix views DistMatrix<C> ATL(g), ATR(g), A00(g), a01(g), A02(g), alpha12L(g), a12R(g), ABL(g), ABR(g), a10(g), alpha11(g), a12(g), aB1(g), AB2(g), A20(g), a21(g), A22(g); // Temporary matrices DistMatrix<C,STAR,MR > a12_STAR_MR(g); DistMatrix<C,MC, STAR> aB1_MC_STAR(g); DistMatrix<C,MR, STAR> x12Adj_MR_STAR(g); DistMatrix<C,MC, STAR> w21_MC_STAR(g); PushBlocksizeStack( 1 ); PartitionDownDiagonal ( A, ATL, ATR, ABL, ABR, 0 ); while( ATL.Width() < A.Width() ) { RepartitionDownDiagonal ( ATL, /**/ ATR, A00, /**/ a01, A02, /*************/ /**********************/ /**/ a10, /**/ alpha11, a12, ABL, /**/ ABR, A20, /**/ a21, A22 ); View2x1 ( aB1, alpha11, a21 ); View2x1 ( AB2, a12, A22 ); aB1_MC_STAR.AlignWith( aB1 ); a12_STAR_MR.AlignWith( a12 ); x12Adj_MR_STAR.AlignWith( AB2 ); w21_MC_STAR.AlignWith( A22 ); Zeros( a12.Width(), 1, x12Adj_MR_STAR ); Zeros( a21.Height(), 1, w21_MC_STAR ); const bool thisIsMyRow = ( g.Row() == alpha11.ColAlignment() ); const bool thisIsMyCol = ( g.Col() == alpha11.RowAlignment() ); const bool nextIsMyCol = ( g.Col() == a12.RowAlignment() ); //--------------------------------------------------------------------// // Find tauQ, u, and epsilonQ such that // I - conj(tauQ) | 1 | | 1, u^H | | alpha11 | = | epsilonQ | // | u | | a21 | | 0 | const C tauQ = Reflector( alpha11, a21 ); tQ.Set(A00.Height(),0,tauQ ); C epsilonQ=0; if( thisIsMyCol && thisIsMyRow ) epsilonQ = alpha11.GetLocal(0,0); // Set aB1 = | 1 | and form x12^H := (aB1^H AB2)^H = AB2^H aB1 // | u | alpha11.Set(0,0,C(1)); aB1_MC_STAR = aB1; internal::LocalGemv ( ADJOINT, C(1), AB2, aB1_MC_STAR, C(0), x12Adj_MR_STAR ); x12Adj_MR_STAR.SumOverCol(); // Update AB2 := AB2 - conj(tauQ) aB1 x12 // = AB2 - conj(tauQ) aB1 aB1^H AB2 // = (I - conj(tauQ) aB1 aB1^H) AB2 internal::LocalGer( -Conj(tauQ), aB1_MC_STAR, x12Adj_MR_STAR, AB2 ); // Put epsilonQ back instead of the temporary value, 1 if( thisIsMyCol && thisIsMyRow ) alpha11.SetLocal(0,0,epsilonQ); if( A22.Width() != 0 ) { // Due to the deficiencies in the BLAS ?gemv routines, this section // is easier if we temporarily conjugate a12 Conjugate( a12 ); // Expose the subvector we seek to zero, a12R PartitionRight( a12, alpha12L, a12R ); // Find tauP, v, and epsilonP such that // I - conj(tauP) | 1 | | 1, v^H | | alpha12L | = | epsilonP | // | v | | a12R^T | | 0 | const C tauP = Reflector( alpha12L, a12R ); tP.Set(A00.Height(),0,tauP); C epsilonP=0; if( nextIsMyCol && thisIsMyRow ) epsilonP = alpha12L.GetLocal(0,0); // Set a12^T = | 1 | and form w21 := A22 a12^T = A22 | 1 | // | v | | v | alpha12L.Set(0,0,C(1)); a12_STAR_MR = a12; internal::LocalGemv ( NORMAL, C(1), A22, a12_STAR_MR, C(0), w21_MC_STAR ); w21_MC_STAR.SumOverRow(); // A22 := A22 - tauP w21 conj(a12) // = A22 - tauP A22 a12^T conj(a12) // = A22 (I - tauP a12^T conj(a12)) // = A22 conj(I - conj(tauP) a12^H a12) // which compensates for the fact that the reflector was generated // on the conjugated a12. internal::LocalGer( -tauP, w21_MC_STAR, a12_STAR_MR, A22 ); // Put epsilonP back instead of the temporary value, 1 if( nextIsMyCol && thisIsMyRow ) alpha12L.SetLocal(0,0,epsilonP); // Undue the temporary conjugation Conjugate( a12 ); } //--------------------------------------------------------------------// aB1_MC_STAR.FreeAlignments(); a12_STAR_MR.FreeAlignments(); x12Adj_MR_STAR.FreeAlignments(); w21_MC_STAR.FreeAlignments(); SlidePartitionDownDiagonal ( ATL, /**/ ATR, A00, a01, /**/ A02, /**/ a10, alpha11, /**/ a12, /*************/ /**********************/ ABL, /**/ ABR, A20, a21, /**/ A22 ); } PopBlocksizeStack(); #ifndef RELEASE PopCallStack(); #endif }
inline void UnblockedBidiagU( DistMatrix<R>& A ) { #ifndef RELEASE PushCallStack("bidiag::UnblockedBidiagU"); if( A.Height() < A.Width() ) throw std::logic_error("A must be at least as tall as it is wide"); #endif const Grid& g = A.Grid(); // Matrix views DistMatrix<R> ATL(g), ATR(g), A00(g), a01(g), A02(g), alpha12L(g), a12R(g), ABL(g), ABR(g), a10(g), alpha11(g), a12(g), aB1(g), AB2(g), A20(g), a21(g), A22(g); // Temporary matrices DistMatrix<R,STAR,MR > a12_STAR_MR(g); DistMatrix<R,MC, STAR> aB1_MC_STAR(g); DistMatrix<R,MR, STAR> x12Trans_MR_STAR(g); DistMatrix<R,MC, STAR> w21_MC_STAR(g); PushBlocksizeStack( 1 ); PartitionDownDiagonal ( A, ATL, ATR, ABL, ABR, 0 ); while( ATL.Width() < A.Width() ) { RepartitionDownDiagonal ( ATL, /**/ ATR, A00, /**/ a01, A02, /*************/ /**********************/ /**/ a10, /**/ alpha11, a12, ABL, /**/ ABR, A20, /**/ a21, A22 ); View2x1 ( aB1, alpha11, a21 ); View2x1 ( AB2, a12, A22 ); aB1_MC_STAR.AlignWith( aB1 ); a12_STAR_MR.AlignWith( a12 ); x12Trans_MR_STAR.AlignWith( AB2 ); w21_MC_STAR.AlignWith( A22 ); Zeros( a12.Width(), 1, x12Trans_MR_STAR ); Zeros( a21.Height(), 1, w21_MC_STAR ); const bool thisIsMyRow = ( g.Row() == alpha11.ColAlignment() ); const bool thisIsMyCol = ( g.Col() == alpha11.RowAlignment() ); const bool nextIsMyCol = ( g.Col() == a12.RowAlignment() ); //--------------------------------------------------------------------// // Find tauQ, u, and epsilonQ such that // I - tauQ | 1 | | 1, u^T | | alpha11 | = | epsilonQ | // | u | | a21 | = | 0 | const R tauQ = Reflector( alpha11, a21 ); R epsilonQ=0; if( thisIsMyCol && thisIsMyRow ) epsilonQ = alpha11.GetLocal(0,0); // Set aB1 = | 1 | and form x12^T := (aB1^T AB2)^T = AB2^T aB1 // | u | alpha11.Set(0,0,R(1)); aB1_MC_STAR = aB1; internal::LocalGemv ( TRANSPOSE, R(1), AB2, aB1_MC_STAR, R(0), x12Trans_MR_STAR ); x12Trans_MR_STAR.SumOverCol(); // Update AB2 := AB2 - tauQ aB1 x12 // = AB2 - tauQ aB1 aB1^T AB2 // = (I - tauQ aB1 aB1^T) AB2 internal::LocalGer( -tauQ, aB1_MC_STAR, x12Trans_MR_STAR, AB2 ); // Put epsilonQ back instead of the temporary value, 1 if( thisIsMyCol && thisIsMyRow ) alpha11.SetLocal(0,0,epsilonQ); if( A22.Width() != 0 ) { // Expose the subvector we seek to zero, a12R PartitionRight( a12, alpha12L, a12R ); // Find tauP, v, and epsilonP such that // I - tauP | 1 | | 1, v^T | | alpha12L | = | epsilonP | // | v | | a12R^T | = | 0 | const R tauP = Reflector( alpha12L, a12R ); R epsilonP=0; if( nextIsMyCol && thisIsMyRow ) epsilonP = alpha12L.GetLocal(0,0); // Set a12^T = | 1 | and form w21 := A22 a12^T = A22 | 1 | // | v | | v | alpha12L.Set(0,0,R(1)); a12_STAR_MR = a12; internal::LocalGemv ( NORMAL, R(1), A22, a12_STAR_MR, R(0), w21_MC_STAR ); w21_MC_STAR.SumOverRow(); // A22 := A22 - tauP w21 a12 // = A22 - tauP A22 a12^T a12 // = A22 (I - tauP a12^T a12) internal::LocalGer( -tauP, w21_MC_STAR, a12_STAR_MR, A22 ); // Put epsilonP back instead of the temporary value, 1 if( nextIsMyCol && thisIsMyRow ) alpha12L.SetLocal(0,0,epsilonP); } //--------------------------------------------------------------------// aB1_MC_STAR.FreeAlignments(); a12_STAR_MR.FreeAlignments(); x12Trans_MR_STAR.FreeAlignments(); w21_MC_STAR.FreeAlignments(); SlidePartitionDownDiagonal ( ATL, /**/ ATR, A00, a01, /**/ A02, /**/ a10, alpha11, /**/ a12, /*************/ /**********************/ ABL, /**/ ABR, A20, a21, /**/ A22 ); } PopBlocksizeStack(); #ifndef RELEASE PopCallStack(); #endif }
inline void PanelLQ( DistMatrix<Real>& A ) { #ifndef RELEASE PushCallStack("internal::PanelLQ"); #endif const Grid& g = A.Grid(); // Matrix views DistMatrix<Real> ATL(g), ATR(g), A00(g), a01(g), A02(g), aTopRow(g), ABottomPan(g), ABL(g), ABR(g), a10(g), alpha11(g), a12(g), A20(g), a21(g), A22(g); // Temporary distributions DistMatrix<Real,STAR,MR> aTopRow_STAR_MR(g); DistMatrix<Real,MC,STAR> z_MC_STAR(g); PushBlocksizeStack( 1 ); PartitionDownLeftDiagonal ( A, ATL, ATR, ABL, ABR, 0 ); while( ATL.Height() < A.Height() && ATL.Width() < A.Width() ) { RepartitionDownDiagonal ( ATL, /**/ ATR, A00, /**/ a01, A02, /*************/ /**********************/ /**/ a10, /**/ alpha11, a12, ABL, /**/ ABR, A20, /**/ a21, A22 ); aTopRow.View1x2( alpha11, a12 ); ABottomPan.View1x2( a21, A22 ); aTopRow_STAR_MR.AlignWith( ABottomPan ); z_MC_STAR.AlignWith( ABottomPan ); Zeros( ABottomPan.Height(), 1, z_MC_STAR ); //--------------------------------------------------------------------// const Real tau = Reflector( alpha11, a12 ); const bool myDiagonalEntry = ( g.Row() == alpha11.ColAlignment() && g.Col() == alpha11.RowAlignment() ); Real alpha = 0; if( myDiagonalEntry ) { alpha = alpha11.GetLocal(0,0); alpha11.SetLocal(0,0,1); } aTopRow_STAR_MR = aTopRow; Gemv ( NORMAL, Real(1), ABottomPan.LockedLocalMatrix(), aTopRow_STAR_MR.LockedLocalMatrix(), Real(0), z_MC_STAR.LocalMatrix() ); z_MC_STAR.SumOverRow(); Ger ( -tau, z_MC_STAR.LockedLocalMatrix(), aTopRow_STAR_MR.LockedLocalMatrix(), ABottomPan.LocalMatrix() ); if( myDiagonalEntry ) alpha11.SetLocal(0,0,alpha); //--------------------------------------------------------------------// aTopRow_STAR_MR.FreeAlignments(); z_MC_STAR.FreeAlignments(); SlidePartitionDownDiagonal ( ATL, /**/ ATR, A00, a01, /**/ A02, /**/ a10, alpha11, /**/ a12, /*************/ /**********************/ ABL, /**/ ABR, A20, a21, /**/ A22 ); } PopBlocksizeStack(); #ifndef RELEASE PopCallStack(); #endif }
inline void PanelLQ ( DistMatrix<Complex<Real> >& A, DistMatrix<Complex<Real>,MD,STAR>& t ) { #ifndef RELEASE PushCallStack("internal::PanelLQ"); if( A.Grid() != t.Grid() ) throw std::logic_error("{A,t} must be distributed over the same grid"); if( t.Height() != std::min(A.Height(),A.Width()) || t.Width() != 1 ) throw std::logic_error ("t must be a vector of height equal to the minimum dimension of A"); if( !t.AlignedWithDiagonal( A, 0 ) ) throw std::logic_error("t must be aligned with A's main diagonal"); #endif typedef Complex<Real> C; const Grid& g = A.Grid(); // Matrix views DistMatrix<C> ATL(g), ATR(g), A00(g), a01(g), A02(g), aTopRow(g), ABottomPan(g), ABL(g), ABR(g), a10(g), alpha11(g), a12(g), A20(g), a21(g), A22(g); DistMatrix<C,MD,STAR> tT(g), t0(g), tB(g), tau1(g), t2(g); // Temporary distributions DistMatrix<C> aTopRowConj(g); DistMatrix<C,STAR,MR > aTopRowConj_STAR_MR(g); DistMatrix<C,MC, STAR> z_MC_STAR(g); PushBlocksizeStack( 1 ); PartitionDownLeftDiagonal ( A, ATL, ATR, ABL, ABR, 0 ); PartitionDown ( t, tT, tB, 0 ); while( ATL.Height() < A.Height() && ATL.Width() < A.Width() ) { RepartitionDownDiagonal ( ATL, /**/ ATR, A00, /**/ a01, A02, /*************/ /**********************/ /**/ a10, /**/ alpha11, a12, ABL, /**/ ABR, A20, /**/ a21, A22 ); RepartitionDown ( tT, t0, /**/ /****/ tau1, tB, t2 ); aTopRow.View1x2( alpha11, a12 ); ABottomPan.View1x2( a21, A22 ); aTopRowConj_STAR_MR.AlignWith( ABottomPan ); z_MC_STAR.AlignWith( ABottomPan ); Zeros( ABottomPan.Height(), 1, z_MC_STAR ); //--------------------------------------------------------------------// const C tau = Reflector( alpha11, a12 ); tau1.Set( 0, 0, tau ); const bool myDiagonalEntry = ( g.Row() == alpha11.ColAlignment() && g.Col() == alpha11.RowAlignment() ); C alpha = 0; if( myDiagonalEntry ) { alpha = alpha11.GetLocal(0,0); alpha11.SetLocal(0,0,1); } Conjugate( aTopRow, aTopRowConj ); aTopRowConj_STAR_MR = aTopRowConj; Gemv ( NORMAL, C(1), ABottomPan.LockedLocalMatrix(), aTopRowConj_STAR_MR.LockedLocalMatrix(), C(0), z_MC_STAR.LocalMatrix() ); z_MC_STAR.SumOverRow(); Ger ( -Conj(tau), z_MC_STAR.LockedLocalMatrix(), aTopRowConj_STAR_MR.LockedLocalMatrix(), ABottomPan.LocalMatrix() ); if( myDiagonalEntry ) alpha11.SetLocal(0,0,alpha); //--------------------------------------------------------------------// aTopRowConj_STAR_MR.FreeAlignments(); z_MC_STAR.FreeAlignments(); SlidePartitionDown ( tT, t0, tau1, /**/ /****/ tB, t2 ); SlidePartitionDownDiagonal ( ATL, /**/ ATR, A00, a01, /**/ A02, /**/ a10, alpha11, /**/ a12, /*************/ /**********************/ ABL, /**/ ABR, A20, a21, /**/ A22 ); } PopBlocksizeStack(); #ifndef RELEASE PopCallStack(); #endif }
inline void PanelLQ ( Matrix<Complex<Real> >& A, Matrix<Complex<Real> >& t ) { #ifndef RELEASE PushCallStack("internal::PanelLQ"); if( t.Height() != std::min(A.Height(),A.Width()) || t.Width() != 1 ) throw std::logic_error ("t must be a vector of height equal to the minimum dimension of A"); #endif typedef Complex<Real> C; Matrix<C> ATL, ATR, A00, a01, A02, aTopRow, ABottomPan, ABL, ABR, a10, alpha11, a12, A20, a21, A22; Matrix<C> tT, t0, tB, tau1, t2; Matrix<C> z, aTopRowConj; PushBlocksizeStack( 1 ); PartitionDownLeftDiagonal ( A, ATL, ATR, ABL, ABR, 0 ); PartitionDown ( t, tT, tB, 0 ); while( ATL.Height() < A.Height() && ATL.Width() < A.Width() ) { RepartitionDownDiagonal ( ATL, /**/ ATR, A00, /**/ a01, A02, /*************/ /**********************/ /**/ a10, /**/ alpha11, a12, ABL, /**/ ABR, A20, /**/ a21, A22 ); RepartitionDown ( tT, t0, /**/ /****/ tau1, tB, t2 ); aTopRow.View1x2( alpha11, a12 ); ABottomPan.View1x2( a21, A22 ); Zeros( ABottomPan.Height(), 1, z ); //--------------------------------------------------------------------// const C tau = Reflector( alpha11, a12 ); tau1.Set( 0, 0, tau ); const C alpha = alpha11.Get(0,0); alpha11.Set(0,0,1); Conjugate( aTopRow, aTopRowConj ); Gemv( NORMAL, C(1), ABottomPan, aTopRowConj, C(0), z ); Ger( -Conj(tau), z, aTopRowConj, ABottomPan ); alpha11.Set(0,0,alpha); //--------------------------------------------------------------------// SlidePartitionDown ( tT, t0, tau1, /**/ /****/ tB, t2 ); SlidePartitionDownDiagonal ( ATL, /**/ ATR, A00, a01, /**/ A02, /**/ a10, alpha11, /**/ a12, /*************/ /**********************/ ABL, /**/ ABR, A20, a21, /**/ A22 ); } PopBlocksizeStack(); #ifndef RELEASE PopCallStack(); #endif }
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 }