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 ); } }
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 HPSDCholesky( UpperOrLower uplo, DistMatrix<Complex<R>,MC,MR>& A ) { #ifndef RELEASE PushCallStack("HPSDCholesky"); #endif HPSDSquareRoot( uplo, A ); hpsd_cholesky::MakeExplicitlyHermitian( uplo, A ); const Grid& g = A.Grid(); if( uplo == LOWER ) { DistMatrix<Complex<R>,MD,STAR> t(g); LQ( A, t ); MakeTrapezoidal( LEFT, LOWER, 0, A ); } else { DistMatrix<Complex<R>,MD,STAR> t(g); QR( A, t ); MakeTrapezoidal( RIGHT, UPPER, 0, A ); } #ifndef RELEASE PopCallStack(); #endif }
void MakeExplicitlyHermitian( UpperOrLower uplo, DistMatrix<F,MC,MR>& A ) { const Grid& g = A.Grid(); DistMatrix<F,MC,MR> ATL(g), ATR(g), A00(g), A01(g), A02(g), ABL(g), ABR(g), A10(g), A11(g), A12(g), A20(g), A21(g), A22(g); DistMatrix<F,MC,MR> A11Adj(g); DistMatrix<F,MR,MC> A11_MR_MC(g); DistMatrix<F,MR,MC> A21_MR_MC(g); DistMatrix<F,MR,MC> A12_MR_MC(g); PartitionDownDiagonal ( A, ATL, ATR, ABL, ABR, 0 ); while( ATL.Height() < A.Height() ) { RepartitionDownDiagonal ( ATL, /**/ ATR, A00, /**/ A01, A02, /*************/ /******************/ /**/ A10, /**/ A11, A12, ABL, /**/ ABR, A20, /**/ A21, A22 ); A11Adj.AlignWith( A11 ); A11_MR_MC.AlignWith( A11 ); A12_MR_MC.AlignWith( A21 ); A21_MR_MC.AlignWith( A12 ); //--------------------------------------------------------------------// A11_MR_MC = A11; A11Adj.ResizeTo( A11.Height(), A11.Width() ); Adjoint( A11_MR_MC.LocalMatrix(), A11Adj.LocalMatrix() ); if( uplo == LOWER ) { MakeTrapezoidal( LEFT, UPPER, 1, A11Adj ); Axpy( (F)1, A11Adj, A11 ); A21_MR_MC = A21; Adjoint( A21_MR_MC.LocalMatrix(), A12.LocalMatrix() ); } else { MakeTrapezoidal( LEFT, LOWER, -1, A11Adj ); Axpy( (F)1, A11Adj, A11 ); A12_MR_MC = A12; Adjoint( A12_MR_MC.LocalMatrix(), A21.LocalMatrix() ); } //--------------------------------------------------------------------// A21_MR_MC.FreeAlignments(); A12_MR_MC.FreeAlignments(); A11_MR_MC.FreeAlignments(); A11Adj.FreeAlignments(); SlidePartitionDownDiagonal ( ATL, /**/ ATR, A00, A01, /**/ A02, /**/ A10, A11, /**/ A12, /*************/ /******************/ ABL, /**/ ABR, A20, A21, /**/ A22 ); } }
inline typename Base<F>::type LogDetDivergence ( UpperOrLower uplo, const DistMatrix<F>& A, const DistMatrix<F>& B ) { #ifndef RELEASE PushCallStack("LogDetDivergence"); #endif if( A.Grid() != B.Grid() ) throw std::logic_error("A and B must use the same grid"); if( A.Height() != A.Width() || B.Height() != B.Width() || A.Height() != B.Height() ) throw std::logic_error ("A and B must be square matrices of the same size"); typedef typename Base<F>::type R; const int n = A.Height(); const Grid& g = A.Grid(); DistMatrix<F> ACopy( A ); DistMatrix<F> BCopy( B ); Cholesky( uplo, ACopy ); Cholesky( uplo, BCopy ); if( uplo == LOWER ) { Trtrsm( LEFT, uplo, NORMAL, NON_UNIT, F(1), BCopy, ACopy ); } else { MakeTrapezoidal( LEFT, uplo, 0, ACopy ); Trsm( LEFT, uplo, NORMAL, NON_UNIT, F(1), BCopy, ACopy ); } MakeTrapezoidal( LEFT, uplo, 0, ACopy ); const R frobNorm = Norm( ACopy, FROBENIUS_NORM ); R logDet; R localLogDet(0); DistMatrix<F,MD,STAR> d(g); ACopy.GetDiagonal( d ); if( d.InDiagonal() ) { const int nLocalDiag = d.LocalHeight(); for( int iLocal=0; iLocal<nLocalDiag; ++iLocal ) { const R delta = RealPart(d.GetLocal(iLocal,0)); localLogDet += 2*Log(delta); } } mpi::AllReduce( &localLogDet, &logDet, 1, mpi::SUM, g.VCComm() ); const R logDetDiv = frobNorm*frobNorm - logDet - R(n); #ifndef RELEASE PopCallStack(); #endif return logDetDiv; }
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 ); } }
void Explicit( AbstractDistMatrix<F>& L, AbstractDistMatrix<F>& APre ) { EL_DEBUG_CSE const Grid& g = APre.Grid(); DistMatrixReadWriteProxy<F,F,MC,MR> AProx( APre ); auto& A = AProx.Get(); DistMatrix<F,MD,STAR> householderScalars(g); DistMatrix<Base<F>,MD,STAR> signature(g); LQ( A, householderScalars, signature ); const Int m = A.Height(); const Int n = A.Width(); const Int minDim = Min(m,n); auto AL = A( IR(0,m), IR(0,minDim) ); Copy( AL, L ); MakeTrapezoidal( LOWER, L ); // TODO: Replace this with an in-place expansion of Q DistMatrix<F> Q(g); Identity( Q, A.Height(), A.Width() ); lq::ApplyQ( RIGHT, NORMAL, A, householderScalars, signature, Q ); Copy( Q, APre ); }
inline void SingularValuesUpper ( DistMatrix<Complex<Real> >& A, DistMatrix<Real,VR,STAR>& s, double heightRatio=1.2 ) { #ifndef RELEASE PushCallStack("svd::SingularValuesUpper"); if( heightRatio <= 1.0 ) throw std::logic_error("Nonsensical switchpoint for SingularValues"); #endif typedef Complex<Real> C; const Grid& g = A.Grid(); const int m = A.Height(); const int n = A.Width(); if( m >= heightRatio*n ) { DistMatrix<C,MD,STAR> t(g); QR( A, t ); DistMatrix<C> AT(g), AB(g); PartitionDown ( A, AT, AB, n ); MakeTrapezoidal( LEFT, UPPER, 0, AT ); SimpleSingularValuesUpper( AT, s ); } else { SimpleSingularValuesUpper( A, s ); } #ifndef RELEASE PopCallStack(); #endif }
void HermitianFromEVD ( UpperOrLower uplo, AbstractDistMatrix<F>& APre, const AbstractDistMatrix<Base<F>>& wPre, const AbstractDistMatrix<F>& ZPre ) { DEBUG_CSE typedef Base<F> Real; DistMatrixWriteProxy<F,F,MC,MR> AProx( APre ); DistMatrixReadProxy<Real,Real,VR,STAR> wProx( wPre ); DistMatrixReadProxy<F,F,MC,MR> ZProx( ZPre ); auto& A = AProx.Get(); auto& w = wProx.GetLocked(); auto& Z = ZProx.GetLocked(); const Grid& g = A.Grid(); DistMatrix<F,MC, STAR> Z1_MC_STAR(g); DistMatrix<F,VR, STAR> Z1_VR_STAR(g); DistMatrix<F,STAR,MR > Z1Adj_STAR_MR(g); 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 ); Z1_MC_STAR.AlignWith( A ); Z1_MC_STAR = Z1; Z1_VR_STAR.AlignWith( A ); Z1_VR_STAR = Z1_MC_STAR; DiagonalScale( RIGHT, NORMAL, w1, Z1_VR_STAR ); Z1Adj_STAR_MR.AlignWith( A ); Adjoint( Z1_VR_STAR, Z1Adj_STAR_MR ); LocalTrrk( uplo, F(1), Z1_MC_STAR, Z1Adj_STAR_MR, F(1), A ); } }
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 ); } }
void ExplicitTriang( Matrix<F>& A ) { DEBUG_ONLY(CSE cse("rq::ExplicitTriang")) Matrix<F> t; Matrix<Base<F>> d; Householder( A, t, d ); MakeTrapezoidal( UPPER, A, A.Width()-A.Height() ); }
void ExplicitTriang( ElementalMatrix<F>& A ) { DEBUG_ONLY(CSE cse("rq::ExplicitTriang")) DistMatrix<F,MD,STAR> t(A.Grid()); DistMatrix<Base<F>,MD,STAR> d(A.Grid()); Householder( A, t, d ); MakeTrapezoidal( UPPER, A, A.Width()-A.Height() ); }
void ExplicitTriang( AbstractDistMatrix<F>& A ) { DEBUG_ONLY(CallStackEntry cse("rq::ExplicitTriang")) DistMatrix<F,MD,STAR> t(A.Grid()); DistMatrix<Base<F>,MD,STAR> d(A.Grid()); Householder( A, t, d ); MakeTrapezoidal( UPPER, A, A.Width()-A.Height() ); }
inline typename Base<F>::type LogDetDivergence( UpperOrLower uplo, const Matrix<F>& A, const Matrix<F>& B ) { #ifndef RELEASE PushCallStack("LogDetDivergence"); #endif if( A.Height() != A.Width() || B.Height() != B.Width() || A.Height() != B.Height() ) throw std::logic_error ("A and B must be square matrices of the same size"); typedef typename Base<F>::type R; const int n = A.Height(); Matrix<F> ACopy( A ); Matrix<F> BCopy( B ); Cholesky( uplo, ACopy ); Cholesky( uplo, BCopy ); if( uplo == LOWER ) { Trtrsm( LEFT, uplo, NORMAL, NON_UNIT, F(1), BCopy, ACopy ); } else { MakeTrapezoidal( LEFT, uplo, 0, ACopy ); Trsm( LEFT, uplo, NORMAL, NON_UNIT, F(1), BCopy, ACopy ); } MakeTrapezoidal( LEFT, uplo, 0, ACopy ); const R frobNorm = Norm( ACopy, FROBENIUS_NORM ); Matrix<F> d; ACopy.GetDiagonal( d ); R logDet(0); for( int i=0; i<n; ++i ) logDet += 2*Log( RealPart(d.Get(i,0)) ); const R logDetDiv = frobNorm*frobNorm - logDet - R(n); #ifndef RELEASE PopCallStack(); #endif return logDetDiv; }
void ExplicitTriang( Matrix<F>& A ) { DEBUG_ONLY(CallStackEntry cse("lq::ExplicitTriang")) Matrix<F> t; Matrix<Base<F>> d; LQ( A, t, d ); const Int m = A.Height(); const Int n = A.Width(); const Int minDim = Min(m,n); A.Resize( m, minDim ); MakeTrapezoidal( LOWER, A ); }
void ExplicitTriang( Matrix<F>& A ) { EL_DEBUG_CSE Matrix<F> householderScalars; Matrix<Base<F>> signature; LQ( A, householderScalars, signature ); const Int m = A.Height(); const Int n = A.Width(); const Int minDim = Min(m,n); A.Resize( m, minDim ); MakeTrapezoidal( LOWER, A ); }
inline void ExplicitLQHelper( Matrix<Real>& L, Matrix<Real>& A ) { LQ( A ); L = A; MakeTrapezoidal( LEFT, LOWER, 0, L ); // TODO: Replace this with an in-place expansion of Q Matrix<Real> Q; Identity( A.Height(), A.Width(), Q ); ApplyPackedReflectors( RIGHT, UPPER, HORIZONTAL, BACKWARD, 0, A, Q ); A = Q; }
void ExplicitTriang( AbstractDistMatrix<F>& A ) { EL_DEBUG_CSE const Grid& g = A.Grid(); DistMatrix<F,MD,STAR> householderScalars(g); DistMatrix<Base<F>,MD,STAR> signature(g); LQ( A, householderScalars, signature ); const Int m = A.Height(); const Int n = A.Width(); const Int minDim = Min(m,n); A.Resize( m, minDim ); MakeTrapezoidal( LOWER, A ); }
inline void HPSDCholesky( UpperOrLower uplo, DistMatrix<R,MC,MR>& A ) { #ifndef RELEASE PushCallStack("HPSDCholesky"); #endif HPSDSquareRoot( uplo, A ); hpsd_cholesky::MakeExplicitlyHermitian( uplo, A ); if( uplo == LOWER ) { LQ( A ); MakeTrapezoidal( LEFT, LOWER, 0, A ); } else { QR( A ); MakeTrapezoidal( RIGHT, UPPER, 0, A ); } #ifndef RELEASE PopCallStack(); #endif }
void ExplicitTriang( Matrix<F>& A, const QRCtrl<Base<F>>& ctrl ) { DEBUG_CSE Matrix<F> householderScalars; Matrix<Base<F>> signature; if( ctrl.colPiv ) { Permutation Omega; BusingerGolub( A, householderScalars, signature, Omega, ctrl ); } else Householder( A, householderScalars, signature ); A.Resize( householderScalars.Height(), A.Width() ); MakeTrapezoidal( UPPER, A ); }
void ExplicitTriang( Matrix<F>& A, const QRCtrl<Base<F>>& ctrl ) { DEBUG_ONLY(CSE cse("qr::ExplicitTriang")) Matrix<F> t; Matrix<Base<F>> d; if( ctrl.colPiv ) { Permutation Omega; BusingerGolub( A, t, d, Omega, ctrl ); } else Householder( A, t, d ); A.Resize( t.Height(), A.Width() ); MakeTrapezoidal( UPPER, A ); }
void ExplicitTriang( AbstractDistMatrix<F>& A, const QRCtrl<Base<F>>& ctrl ) { DEBUG_ONLY(CallStackEntry cse("qr::ExplicitTriang")) DistMatrix<F,MD,STAR> t(A.Grid()); DistMatrix<Base<F>,MD,STAR> d(A.Grid()); if( ctrl.colPiv ) { DistMatrix<Int,VC,STAR> p(A.Grid()); BusingerGolub( A, t, d, p, ctrl ); } else Householder( A, t, d ); A.Resize( t.Height(), A.Width() ); MakeTrapezoidal( UPPER, A ); }
void ExplicitTriang( Matrix<F>& A, const QRCtrl<Base<F>>& ctrl ) { DEBUG_ONLY(CallStackEntry cse("qr::ExplicitTriang")) Matrix<F> t; Matrix<Base<F>> d; if( ctrl.colPiv ) { Matrix<Int> p; BusingerGolub( A, t, d, p, ctrl ); } else Householder( A, t, d ); A.Resize( t.Height(), A.Width() ); MakeTrapezoidal( UPPER, A ); }
void ExplicitTriang( ElementalMatrix<F>& A, const QRCtrl<Base<F>>& ctrl ) { DEBUG_ONLY(CSE cse("qr::ExplicitTriang")) DistMatrix<F,MD,STAR> t(A.Grid()); DistMatrix<Base<F>,MD,STAR> d(A.Grid()); if( ctrl.colPiv ) { DistPermutation Omega(A.Grid()); BusingerGolub( A, t, d, Omega, ctrl ); } else Householder( A, t, d ); A.Resize( t.Height(), A.Width() ); MakeTrapezoidal( UPPER, A ); }
void ExplicitTriang( ElementalMatrix<F>& A, const QRCtrl<Base<F>>& ctrl ) { DEBUG_CSE DistMatrix<F,MD,STAR> householderScalars(A.Grid()); DistMatrix<Base<F>,MD,STAR> signature(A.Grid()); if( ctrl.colPiv ) { DistPermutation Omega(A.Grid()); BusingerGolub( A, householderScalars, signature, Omega, ctrl ); } else Householder( A, householderScalars, signature ); A.Resize( householderScalars.Height(), A.Width() ); MakeTrapezoidal( UPPER, A ); }
inline void ExplicitLQHelper ( DistMatrix<Complex<Real> >& L, DistMatrix<Complex<Real> >& A ) { const Grid& g = A.Grid(); DistMatrix<Complex<Real>,MD,STAR> t( g ); LQ( A, t ); L = A; MakeTrapezoidal( LEFT, LOWER, 0, L ); // TODO: Replace this with an in-place expansion of Q DistMatrix<Complex<Real> > Q( g ); Identity( A.Height(), A.Width(), Q ); ApplyPackedReflectors ( RIGHT, UPPER, HORIZONTAL, BACKWARD, UNCONJUGATED, 0, A, t, Q ); A = Q; }
void Explicit ( ElementalMatrix<F>& APre, ElementalMatrix<F>& R, bool thinQR, const QRCtrl<Base<F>>& ctrl ) { DEBUG_CSE DistMatrixReadWriteProxy<F,F,MC,MR> AProx( APre ); auto& A = AProx.Get(); const Grid& g = A.Grid(); DistMatrix<F,MD,STAR> householderScalars(g); DistMatrix<Base<F>,MD,STAR> signature(g); if( ctrl.colPiv ) { DistPermutation Omega(g); QR( A, householderScalars, signature, Omega, ctrl ); } else QR( A, householderScalars, signature ); const Int m = A.Height(); const Int n = A.Width(); const Int numIts = householderScalars.Height(); auto AT = A( IR(0,numIts), IR(0,n) ); Copy( AT, R ); MakeTrapezoidal( UPPER, R ); if( thinQR ) { A.Resize( m, numIts ); ExpandPackedReflectors ( LOWER, VERTICAL, CONJUGATED, 0, A, householderScalars ); DiagonalScale( RIGHT, NORMAL, signature, A ); } else { auto ACopy = A; // TODO: Use an extension of ExpandPackedReflectors to make this faster Identity( A, A.Height(), A.Height() ); qr::ApplyQ( LEFT, NORMAL, ACopy, householderScalars, signature, A ); } }
void Explicit ( ElementalMatrix<F>& APre, ElementalMatrix<F>& R, ElementalMatrix<Int>& OmegaFull, bool thinQR, const QRCtrl<Base<F>>& ctrl ) { DEBUG_ONLY(CSE cse("qr::Explicit")) DistMatrixReadWriteProxy<F,F,MC,MR> AProx( APre ); auto& A = AProx.Get(); const Grid& g = A.Grid(); DistMatrix<F,MD,STAR> t(g); DistMatrix<Base<F>,MD,STAR> d(g); DistPermutation Omega(g); QR( A, t, d, Omega, ctrl ); const Int m = A.Height(); const Int n = A.Width(); const Int numIts = t.Height(); auto AT = A( IR(0,numIts), IR(0,n) ); Copy( AT, R ); MakeTrapezoidal( UPPER, R ); if( thinQR ) { A.Resize( m, numIts ); ExpandPackedReflectors( LOWER, VERTICAL, CONJUGATED, 0, A, t ); DiagonalScale( RIGHT, NORMAL, d, A ); } else { auto ACopy = A; // TODO: Use an extension of ExpandPackedReflectors to make this faster Identity( A, A.Height(), A.Height() ); qr::ApplyQ( LEFT, NORMAL, ACopy, t, d, A ); } Omega.ExplicitMatrix( OmegaFull ); }
void Explicit( Matrix<F>& L, Matrix<F>& A ) { EL_DEBUG_CSE Matrix<F> householderScalars; Matrix<Base<F>> signature; LQ( A, householderScalars, signature ); const Int m = A.Height(); const Int n = A.Width(); const Int minDim = Min(m,n); auto AL = A( IR(0,m), IR(0,minDim) ); L = AL; MakeTrapezoidal( LOWER, L ); // TODO: Replace this with an in-place expansion of Q Matrix<F> Q; Identity( Q, A.Height(), A.Width() ); lq::ApplyQ( RIGHT, NORMAL, A, householderScalars, signature, Q ); A = Q; }
void Explicit ( Matrix<F>& A, Matrix<F>& R, bool thinQR, const QRCtrl<Base<F>>& ctrl ) { DEBUG_CSE Matrix<F> householderScalars; Matrix<Base<F>> signature; if( ctrl.colPiv ) { Permutation Omega; QR( A, householderScalars, signature, Omega, ctrl ); } else QR( A, householderScalars, signature ); const Int m = A.Height(); const Int n = A.Width(); const Int numIts = householderScalars.Height(); auto AT = A( IR(0,numIts), IR(0,n) ); R = AT; MakeTrapezoidal( UPPER, R ); if( thinQR ) { A.Resize( m, numIts ); ExpandPackedReflectors ( LOWER, VERTICAL, CONJUGATED, 0, A, householderScalars ); DiagonalScale( RIGHT, NORMAL, signature, A ); } else { auto ACopy = A; // TODO: Use an extension of ExpandPackedReflectors to make this faster Identity( A, A.Height(), A.Height() ); qr::ApplyQ( LEFT, NORMAL, ACopy, householderScalars, signature, A ); } }