inline Int RegularizedSolveAfterNoPromote ( const SparseMatrix<F>& A, const Matrix<Base<F>>& reg, const Matrix<Base<F>>& d, const vector<Int>& invMap, const ldl::NodeInfo& info, const ldl::Front<F>& front, Matrix<F>& B, Base<F> relTol, Int maxRefineIts, bool progress, bool time ) { DEBUG_CSE // TODO: Use time in these lambdas auto applyA = [&]( const Matrix<F>& X, Matrix<F>& Y ) { Y = X; DiagonalScale( LEFT, NORMAL, reg, Y ); Multiply( NORMAL, F(1), A, X, F(1), Y ); }; auto applyAInv = [&]( Matrix<F>& Y ) { DiagonalSolve( LEFT, NORMAL, d, Y ); ldl::MatrixNode<F> YNodal( invMap, info, Y ); ldl::SolveAfter( info, front, YNodal ); YNodal.Push( invMap, info, Y ); DiagonalSolve( LEFT, NORMAL, d, Y ); }; return RefinedSolve( applyA, applyAInv, B, relTol, maxRefineIts, progress ); }
void SymmetricRuizEquil ( Matrix<F>& A, Matrix<Base<F>>& d, Int maxIter, bool progress ) { DEBUG_CSE typedef Base<F> Real; const Int n = A.Height(); Ones( d, n, 1 ); Matrix<Real> scales; const Int indent = PushIndent(); for( Int iter=0; iter<maxIter; ++iter ) { // Rescale the columns (and rows) // ------------------------------ ColumnMaxNorms( A, scales ); EntrywiseMap( scales, function<Real(Real)>(DampScaling<Real>) ); EntrywiseMap( scales, function<Real(Real)>(SquareRootScaling<Real>) ); DiagonalScale( LEFT, NORMAL, scales, d ); // TODO(poulson): Replace with SymmetricDiagonalSolve DiagonalSolve( RIGHT, NORMAL, scales, A ); DiagonalSolve( LEFT, NORMAL, scales, A ); } SetIndent( indent ); }
void StackedRuizEquil ( DistSparseMatrix<Field>& A, DistSparseMatrix<Field>& B, DistMultiVec<Base<Field>>& dRowA, DistMultiVec<Base<Field>>& dRowB, DistMultiVec<Base<Field>>& dCol, bool progress ) { EL_DEBUG_CSE typedef Base<Field> Real; const Int mA = A.Height(); const Int mB = B.Height(); const Int n = A.Width(); mpi::Comm comm = A.Comm(); dRowA.SetComm( comm ); dRowB.SetComm( comm ); dCol.SetComm( comm ); Ones( dRowA, mA, 1 ); Ones( dRowB, mB, 1 ); Ones( dCol, n, 1 ); // TODO(poulson): Expose to control structure // For, simply hard-code a small number of iterations const Int maxIter = 4; DistMultiVec<Real> scales(comm), maxAbsValsB(comm); auto& scalesLoc = scales.Matrix(); auto& maxAbsValsBLoc = maxAbsValsB.Matrix(); const Int localHeight = scalesLoc.Height(); const Int indent = PushIndent(); for( Int iter=0; iter<maxIter; ++iter ) { // Rescale the columns // ------------------- ColumnMaxNorms( A, scales ); ColumnMaxNorms( B, maxAbsValsB ); for( Int jLoc=0; jLoc<localHeight; ++jLoc ) scalesLoc(jLoc) = Max(scalesLoc(jLoc),maxAbsValsBLoc(jLoc)); EntrywiseMap( scales, MakeFunction(DampScaling<Real>) ); DiagonalScale( LEFT, NORMAL, scales, dCol ); DiagonalSolve( RIGHT, NORMAL, scales, A ); DiagonalSolve( RIGHT, NORMAL, scales, B ); // Rescale the rows // ---------------- RowMaxNorms( A, scales ); EntrywiseMap( scales, MakeFunction(DampScaling<Real>) ); DiagonalScale( LEFT, NORMAL, scales, dRowA ); DiagonalSolve( LEFT, NORMAL, scales, A ); RowMaxNorms( B, scales ); EntrywiseMap( scales, MakeFunction(DampScaling<Real>) ); DiagonalScale( LEFT, NORMAL, scales, dRowB ); DiagonalSolve( LEFT, NORMAL, scales, B ); } SetIndent( indent ); }
void RuizEquil ( AbstractDistMatrix<Field>& APre, AbstractDistMatrix<Base<Field>>& dRowPre, AbstractDistMatrix<Base<Field>>& dColPre, bool progress ) { EL_DEBUG_CSE typedef Base<Field> Real; ElementalProxyCtrl control; control.colConstrain = true; control.rowConstrain = true; control.colAlign = 0; control.rowAlign = 0; DistMatrixReadWriteProxy<Field,Field,MC,MR> AProx( APre, control ); DistMatrixWriteProxy<Real,Real,MC,STAR> dRowProx( dRowPre, control ); DistMatrixWriteProxy<Real,Real,MR,STAR> dColProx( dColPre, control ); auto& A = AProx.Get(); auto& dRow = dRowProx.Get(); auto& dCol = dColProx.Get(); const Int m = A.Height(); const Int n = A.Width(); Ones( dRow, m, 1 ); Ones( dCol, n, 1 ); // TODO(poulson): Expose these as control parameters // For now, simply hard-code the number of iterations const Int maxIter = 4; DistMatrix<Real,MC,STAR> rowScale(A.Grid()); DistMatrix<Real,MR,STAR> colScale(A.Grid()); const Int indent = PushIndent(); for( Int iter=0; iter<maxIter; ++iter ) { // Rescale the columns // ------------------- ColumnMaxNorms( A, colScale ); EntrywiseMap( colScale, MakeFunction(DampScaling<Real>) ); DiagonalScale( LEFT, NORMAL, colScale, dCol ); DiagonalSolve( RIGHT, NORMAL, colScale, A ); // Rescale the rows // ---------------- RowMaxNorms( A, rowScale ); EntrywiseMap( rowScale, MakeFunction(DampScaling<Real>) ); DiagonalScale( LEFT, NORMAL, rowScale, dRow ); DiagonalSolve( LEFT, NORMAL, rowScale, A ); } SetIndent( indent ); }
void StackedRuizEquil ( SparseMatrix<Field>& A, SparseMatrix<Field>& B, Matrix<Base<Field>>& dRowA, Matrix<Base<Field>>& dRowB, Matrix<Base<Field>>& dCol, bool progress ) { EL_DEBUG_CSE typedef Base<Field> Real; const Int mA = A.Height(); const Int mB = B.Height(); const Int n = A.Width(); Ones( dRowA, mA, 1 ); Ones( dRowB, mB, 1 ); Ones( dCol, n, 1 ); // TODO(poulson): Expose these as control parameters // For now, simply hard-code the number of iterations const Int maxIter = 4; Matrix<Real> scales, maxAbsValsB; const Int indent = PushIndent(); for( Int iter=0; iter<maxIter; ++iter ) { // Rescale the columns // ------------------- ColumnMaxNorms( A, scales ); ColumnMaxNorms( B, maxAbsValsB ); for( Int j=0; j<n; ++j ) scales(j) = Max(scales(j),maxAbsValsB(j)); EntrywiseMap( scales, MakeFunction(DampScaling<Real>) ); DiagonalScale( LEFT, NORMAL, scales, dCol ); DiagonalSolve( RIGHT, NORMAL, scales, A ); DiagonalSolve( RIGHT, NORMAL, scales, B ); // Rescale the rows // ---------------- RowMaxNorms( A, scales ); EntrywiseMap( scales, MakeFunction(DampScaling<Real>) ); DiagonalScale( LEFT, NORMAL, scales, dRowA ); DiagonalSolve( LEFT, NORMAL, scales, A ); RowMaxNorms( B, scales ); EntrywiseMap( scales, MakeFunction(DampScaling<Real>) ); DiagonalScale( LEFT, NORMAL, scales, dRowB ); DiagonalSolve( LEFT, NORMAL, scales, B ); } SetIndent( indent ); }
void Pseudoinverse( Matrix<F>& A, Base<F> tolerance ) { DEBUG_CSE typedef Base<F> Real; const Int m = A.Height(); const Int n = A.Width(); const Real eps = limits::Epsilon<Real>(); // Get the SVD of A Matrix<Real> s; Matrix<F> U, V; SVDCtrl<Real> ctrl; ctrl.overwrite = true; ctrl.bidiagSVDCtrl.approach = COMPACT_SVD; // TODO(poulson): Let the user change these defaults ctrl.bidiagSVDCtrl.tolType = RELATIVE_TO_MAX_SING_VAL_TOL; ctrl.bidiagSVDCtrl.tol = ( tolerance == Real(0) ? Max(m,n)*eps : tolerance ); SVD( A, U, s, V, ctrl ); // Scale U with the inverted (nonzero) singular values, U := U / Sigma DiagonalSolve( RIGHT, NORMAL, s, U ); // Form pinvA = (U Sigma V^H)^H = V (U Sigma)^H Gemm( NORMAL, ADJOINT, F(1), V, U, A ); }
void Pseudoinverse( ElementalMatrix<F>& APre, Base<F> tolerance ) { DEBUG_CSE typedef Base<F> Real; DistMatrixReadWriteProxy<F,F,MC,MR> AProx( APre ); auto& A = AProx.Get(); const Int m = A.Height(); const Int n = A.Width(); const Grid& g = A.Grid(); const Real eps = limits::Epsilon<Real>(); // Get the SVD of A DistMatrix<Real,VR,STAR> s(g); DistMatrix<F> U(g), V(g); SVDCtrl<Real> ctrl; ctrl.overwrite = true; ctrl.bidiagSVDCtrl.approach = COMPACT_SVD; // TODO(poulson): Let the user change these defaults ctrl.bidiagSVDCtrl.tolType = RELATIVE_TO_MAX_SING_VAL_TOL; ctrl.bidiagSVDCtrl.tol = ( tolerance == Real(0) ? Max(m,n)*eps : tolerance ); SVD( A, U, s, V, ctrl ); // Scale U with the inverted (nonzero) singular values, U := U / Sigma DiagonalSolve( RIGHT, NORMAL, s, U ); // Form pinvA = (U Sigma V^H)^H = V (U Sigma)^H Gemm( NORMAL, ADJOINT, F(1), V, U, A ); }
void AugmentedKKT ( const ElementalMatrix<Real>& A, const ElementalMatrix<Real>& x, const ElementalMatrix<Real>& z, ElementalMatrix<Real>& JPre, bool onlyLower ) { EL_DEBUG_CSE const Int m = A.Height(); const Int n = A.Width(); DistMatrixWriteProxy<Real,Real,MC,MR> JProx( JPre ); auto& J = JProx.Get(); Zeros( J, m+n, m+n ); const IR xInd(0,n), yInd(n,n+m); auto Jxx = J(xInd,xInd); auto Jxy = J(xInd,yInd); auto Jyx = J(yInd,xInd); auto Jyy = J(yInd,yInd); DistMatrix<Real,MC,STAR> d( z ); DiagonalSolve( LEFT, NORMAL, x, d ); Diagonal( Jxx, d ); Jyx = A; if( !onlyLower ) Transpose( A, Jxy ); }
void RuizEquil ( DistSparseMatrix<Field>& A, DistMultiVec<Base<Field>>& dRow, DistMultiVec<Base<Field>>& dCol, bool progress ) { EL_DEBUG_CSE typedef Base<Field> Real; const Int m = A.Height(); const Int n = A.Width(); mpi::Comm comm = A.Comm(); dRow.SetComm( comm ); dCol.SetComm( comm ); Ones( dRow, m, 1 ); Ones( dCol, n, 1 ); // TODO(poulson): Expose to control structure // For, simply hard-code a small number of iterations const Int maxIter = 4; DistMultiVec<Real> scales(comm); const Int indent = PushIndent(); for( Int iter=0; iter<maxIter; ++iter ) { // Rescale the columns // ------------------- ColumnMaxNorms( A, scales ); EntrywiseMap( scales, MakeFunction(DampScaling<Real>) ); DiagonalScale( LEFT, NORMAL, scales, dCol ); DiagonalSolve( RIGHT, NORMAL, scales, A ); // Rescale the rows // ---------------- RowMaxNorms( A, scales ); EntrywiseMap( scales, MakeFunction(DampScaling<Real>) ); DiagonalScale( LEFT, NORMAL, scales, dRow ); DiagonalSolve( LEFT, NORMAL, scales, A ); } SetIndent( indent ); }
void SymmetricRuizEquil ( ElementalMatrix<F>& APre, ElementalMatrix<Base<F>>& dPre, Int maxIter, bool progress ) { DEBUG_CSE typedef Base<F> Real; ElementalProxyCtrl control; control.colConstrain = true; control.rowConstrain = true; control.colAlign = 0; control.rowAlign = 0; DistMatrixReadWriteProxy<F,F,MC,MR> AProx( APre, control ); DistMatrixWriteProxy<Real,Real,MC,STAR> dProx( dPre, control ); auto& A = AProx.Get(); auto& d = dProx.Get(); const Int n = A.Height(); Ones( d, n, 1 ); DistMatrix<Real,MR,STAR> scales(A.Grid()); const Int indent = PushIndent(); for( Int iter=0; iter<maxIter; ++iter ) { // Rescale the columns (and rows) // ------------------------------ ColumnMaxNorms( A, scales ); EntrywiseMap( scales, function<Real(Real)>(DampScaling<Real>) ); EntrywiseMap( scales, function<Real(Real)>(SquareRootScaling<Real>) ); DiagonalScale( LEFT, NORMAL, scales, d ); // TODO: Replace with SymmetricDiagonalSolve DiagonalSolve( RIGHT, NORMAL, scales, A ); DiagonalSolve( LEFT, NORMAL, scales, A ); } SetIndent( indent ); }
Base<F> Coherence( const ElementalMatrix<F>& A ) { DEBUG_ONLY(CSE cse("Coherence")) DistMatrix<F> B( A ); DistMatrix<Base<F>,MR,STAR> norms(B.Grid()); ColumnTwoNorms( B, norms ); DiagonalSolve( RIGHT, NORMAL, norms, B, true ); DistMatrix<F> C(B.Grid()); Identity( C, A.Width(), A.Width() ); Herk( UPPER, ADJOINT, Base<F>(-1), B, Base<F>(1), C ); return HermitianMaxNorm( UPPER, C ); }
Base<F> Coherence( const Matrix<F>& A ) { DEBUG_ONLY(CallStackEntry cse("Coherence")) Matrix<F> B( A ); Matrix<Base<F>> norms; ColumnNorms( B, norms ); DiagonalSolve( RIGHT, NORMAL, norms, B, true ); Matrix<F> C; Identity( C, A.Width(), A.Width() ); Herk( UPPER, ADJOINT, Base<F>(-1), B, Base<F>(1), C ); return HermitianMaxNorm( UPPER, C ); }
void RuizEquil ( Matrix<Field>& A, Matrix<Base<Field>>& dRow, Matrix<Base<Field>>& dCol, bool progress ) { EL_DEBUG_CSE typedef Base<Field> Real; const Int m = A.Height(); const Int n = A.Width(); Ones( dRow, m, 1 ); Ones( dCol, n, 1 ); // TODO(poulson): Expose these as control parameters // For now, simply hard-code the number of iterations const Int maxIter = 4; Matrix<Real> rowScale, colScale; const Int indent = PushIndent(); for( Int iter=0; iter<maxIter; ++iter ) { // Rescale the columns // ------------------- ColumnMaxNorms( A, colScale ); EntrywiseMap( colScale, MakeFunction(DampScaling<Real>) ); DiagonalScale( LEFT, NORMAL, colScale, dCol ); DiagonalSolve( RIGHT, NORMAL, colScale, A ); // Rescale the rows // ---------------- RowMaxNorms( A, rowScale ); EntrywiseMap( rowScale, MakeFunction(DampScaling<Real>) ); DiagonalScale( LEFT, NORMAL, rowScale, dRow ); DiagonalSolve( LEFT, NORMAL, rowScale, A ); } SetIndent( indent ); }
void KKT ( const ElementalMatrix<Real>& A, const ElementalMatrix<Real>& x, const ElementalMatrix<Real>& z, ElementalMatrix<Real>& JPre, bool onlyLower ) { EL_DEBUG_CSE const Int m = A.Height(); const Int n = A.Width(); DistMatrixWriteProxy<Real,Real,MC,MR> JProx( JPre ); auto& J = JProx.Get(); Zeros( J, 2*n+m, 2*n+m ); const IR xInd(0,n), yInd(n,n+m), zInd(n+m,2*n+m); auto Jxx = J(xInd,xInd); auto Jxy = J(xInd,yInd); auto Jxz = J(xInd,zInd); auto Jyx = J(yInd,xInd); auto Jyy = J(yInd,yInd); auto Jyz = J(yInd,zInd); auto Jzx = J(zInd,xInd); auto Jzy = J(zInd,yInd); auto Jzz = J(zInd,zInd); // Jyx := A // ======== Jyx = A; // Jzx := -I // ========= Identity( Jzx, n, n ); Jzx *= -1; // Jzz := - z <> x // =============== DistMatrix<Real,MC,STAR> t(x); DiagonalSolve( LEFT, NORMAL, z, t ); t *= -1; Diagonal( Jzz, t ); if( !onlyLower ) { // Jxy := A^T // ========== Transpose( A, Jxy ); // Jxz := -I // ========= Identity( Jxz, n, n ); Jxz *= -1; } }
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 }
void KKT ( const Matrix<Real>& A, const Matrix<Real>& G, const Matrix<Real>& s, const Matrix<Real>& z, Matrix<Real>& J, bool onlyLower ) { EL_DEBUG_CSE const Int m = A.Height(); const Int n = A.Width(); const Int k = G.Height(); Zeros( J, n+m+k, n+m+k ); const IR xInd(0,n), yInd(n,n+m), zInd(n+m,n+m+k); auto Jxx = J(xInd,xInd); auto Jxy = J(xInd,yInd); auto Jxz = J(xInd,zInd); auto Jyx = J(yInd,xInd); auto Jyy = J(yInd,yInd); auto Jyz = J(yInd,zInd); auto Jzx = J(zInd,xInd); auto Jzy = J(zInd,yInd); auto Jzz = J(zInd,zInd); // Jyx := A // ======== Jyx = A; // Jzx := G // ======== Jzx = G; // Jzz := - z <> s // =============== Matrix<Real> t; t = s; DiagonalSolve( LEFT, NORMAL, z, t ); t *= -1; Diagonal( Jzz, t ); if( !onlyLower ) { // Jxy := A^T // ========== Transpose( A, Jxy ); // Jxz := G^T // ========== Transpose( G, Jxz ); } }
void KKT ( const Matrix<Real>& A, const Matrix<Real>& x, const Matrix<Real>& z, Matrix<Real>& J, bool onlyLower ) { EL_DEBUG_CSE const Int m = A.Height(); const Int n = A.Width(); Zeros( J, 2*n+m, 2*n+m ); const IR xInd(0,n), yInd(n,n+m), zInd(n+m,2*n+m); auto Jxx = J(xInd,xInd); auto Jxy = J(xInd,yInd); auto Jxz = J(xInd,zInd); auto Jyx = J(yInd,xInd); auto Jyy = J(yInd,yInd); auto Jyz = J(yInd,zInd); auto Jzx = J(zInd,xInd); auto Jzy = J(zInd,yInd); auto Jzz = J(zInd,zInd); // Jyx := A // ======== Jyx = A; // Jzx := -I // ========= Identity( Jzx, n, n ); Jzx *= -1; // Jzz := - z <> x // =============== Matrix<Real> t; t = x; DiagonalSolve( LEFT, NORMAL, z, t ); t *= -1; Diagonal( Jzz, t ); if( !onlyLower ) { // Jxy := A^T // ========== Transpose( A, Jxy ); // Jxz := -I // ========= Identity( Jxz, n, n ); Jxz *= -1; } }
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 ); } }
void AugmentedKKT ( const Matrix<Real>& A, const Matrix<Real>& x, const Matrix<Real>& z, Matrix<Real>& J, bool onlyLower ) { EL_DEBUG_CSE const Int m = A.Height(); const Int n = A.Width(); Zeros( J, m+n, m+n ); const IR xInd(0,n), yInd(n,n+m); auto Jxx = J(xInd,xInd); auto Jxy = J(xInd,yInd); auto Jyx = J(yInd,xInd); auto Jyy = J(yInd,yInd); Matrix<Real> d( z ); DiagonalSolve( LEFT, NORMAL, x, d ); Diagonal( Jxx, d ); Jyx = A; if( !onlyLower ) Transpose( A, Jxy ); }
inline void TrdtrmmUVar1( Orientation orientation, DistMatrix<F>& U ) { #ifndef RELEASE PushCallStack("internal::TrdtrmmUVar1"); 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 const Grid& g = U.Grid(); // Matrix views DistMatrix<F> UTL(g), UTR(g), U00(g), U01(g), U02(g), UBL(g), UBR(g), U10(g), U11(g), U12(g), U20(g), U21(g), U22(g); DistMatrix<F,MD,STAR> d1(g); // Temporary distributions DistMatrix<F,MC, STAR> S01_MC_STAR(g); DistMatrix<F,VC, STAR> S01_VC_STAR(g); DistMatrix<F,VR, STAR> U01_VR_STAR(g); DistMatrix<F,STAR,MR > U01AdjOrTrans_STAR_MR(g); DistMatrix<F,STAR,STAR> U11_STAR_STAR(g); S01_MC_STAR.AlignWith( U ); S01_VC_STAR.AlignWith( U ); U01_VR_STAR.AlignWith( U ); U01AdjOrTrans_STAR_MR.AlignWith( U ); 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_MC_STAR = U01; S01_VC_STAR = S01_MC_STAR; U01_VR_STAR = S01_VC_STAR; if( orientation == TRANSPOSE ) { DiagonalSolve( RIGHT, NORMAL, d1, U01_VR_STAR ); U01AdjOrTrans_STAR_MR.TransposeFrom( U01_VR_STAR ); } else { DiagonalSolve( RIGHT, ADJOINT, d1, U01_VR_STAR ); U01AdjOrTrans_STAR_MR.AdjointFrom( U01_VR_STAR ); } LocalTrrk( UPPER, F(1), S01_MC_STAR, U01AdjOrTrans_STAR_MR, F(1), U00 ); U11_STAR_STAR = U11; LocalTrmm ( RIGHT, UPPER, ADJOINT, UNIT, F(1), U11_STAR_STAR, U01_VR_STAR ); U01 = U01_VR_STAR; LocalTrdtrmm( orientation, UPPER, U11_STAR_STAR ); U11 = U11_STAR_STAR; //--------------------------------------------------------------------// d1.FreeAlignments(); SlidePartitionDownDiagonal ( UTL, /**/ UTR, U00, U01, /**/ U02, /**/ U10, U11, /**/ U12, /*************/ /******************/ UBL, /**/ UBR, U20, U21, /**/ U22 ); } #ifndef RELEASE PopCallStack(); #endif }
inline void Var3( Orientation orientation, DistMatrix<F>& A, DistMatrix<F,MC,STAR>& d ) { #ifndef RELEASE PushCallStack("ldl::Var3"); if( orientation == NORMAL ) throw std::logic_error("Can only perform LDL^T and LDL^H"); if( A.Height() != A.Width() ) throw std::logic_error("A must be square"); if( A.Grid() != d.Grid() ) throw std::logic_error("A and d must use the same grid"); if( d.Viewing() && (d.Height() != A.Height() || d.Width() != 1) ) throw std::logic_error ("d must be a column vector of the same height as A"); if( d.Viewing() && d.ColAlignment() != A.ColAlignment() ) throw std::logic_error("d must be aligned with A"); #endif const Grid& g = A.Grid(); if( !d.Viewing() ) { d.AlignWith( A ); d.ResizeTo( A.Height(), 1 ); } // Matrix views DistMatrix<F> 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,STAR> dT(g), d0(g), dB(g), d1(g), d2(g); // Temporary matrices DistMatrix<F,STAR,STAR> A11_STAR_STAR(g); DistMatrix<F,STAR,STAR> d1_STAR_STAR(g); DistMatrix<F,VC, STAR> A21_VC_STAR(g); DistMatrix<F,VR, STAR> A21_VR_STAR(g); DistMatrix<F,STAR,MC > S21Trans_STAR_MC(g); DistMatrix<F,STAR,MR > A21AdjOrTrans_STAR_MR(g); const bool conjugate = ( orientation == ADJOINT ); // Start the algorithm PartitionDownDiagonal ( A, ATL, ATR, ABL, ABR, 0 ); PartitionDown ( d, dT, dB, 0 ); while( ABR.Height() > 0 ) { RepartitionDownDiagonal ( ATL, /**/ ATR, A00, /**/ A01, A02, /*************/ /******************/ /**/ A10, /**/ A11, A12, ABL, /**/ ABR, A20, /**/ A21, A22 ); RepartitionDown ( dT, d0, /**/ /**/ d1, dB, d2 ); A21_VC_STAR.AlignWith( A22 ); A21_VR_STAR.AlignWith( A22 ); S21Trans_STAR_MC.AlignWith( A22 ); A21AdjOrTrans_STAR_MR.AlignWith( A22 ); //--------------------------------------------------------------------// A11_STAR_STAR = A11; LocalLDL( orientation, A11_STAR_STAR, d1_STAR_STAR ); A11 = A11_STAR_STAR; d1 = d1_STAR_STAR; A21_VC_STAR = A21; LocalTrsm ( RIGHT, LOWER, orientation, UNIT, F(1), A11_STAR_STAR, A21_VC_STAR ); S21Trans_STAR_MC.TransposeFrom( A21_VC_STAR ); DiagonalSolve( RIGHT, NORMAL, d1_STAR_STAR, A21_VC_STAR ); A21_VR_STAR = A21_VC_STAR; A21AdjOrTrans_STAR_MR.TransposeFrom( A21_VR_STAR, conjugate ); LocalTrrk ( LOWER, TRANSPOSE, F(-1), S21Trans_STAR_MC, A21AdjOrTrans_STAR_MR, F(1), A22 ); A21 = A21_VC_STAR; //--------------------------------------------------------------------// A21_VC_STAR.FreeAlignments(); A21_VR_STAR.FreeAlignments(); S21Trans_STAR_MC.FreeAlignments(); A21AdjOrTrans_STAR_MR.FreeAlignments(); SlidePartitionDown ( dT, d0, d1, /**/ /**/ dB, d2 ); SlidePartitionDownDiagonal ( ATL, /**/ ATR, A00, A01, /**/ A02, /**/ A10, A11, /**/ A12, /*************/ /******************/ ABL, /**/ ABR, A20, A21, /**/ A22 ); } #ifndef RELEASE PopCallStack(); #endif }
inline void Var3( Orientation orientation, Matrix<F>& A, Matrix<F>& d ) { #ifndef RELEASE PushCallStack("ldl::Var3"); if( A.Height() != A.Width() ) throw std::logic_error("A must be square"); if( d.Viewing() && (d.Height() != A.Height() || d.Width() != 1) ) throw std::logic_error ("d must be a column vector the same height as A"); if( orientation == NORMAL ) throw std::logic_error("Can only perform LDL^T or LDL^H"); #endif const int n = A.Height(); if( !d.Viewing() ) d.ResizeTo( n, 1 ); Matrix<F> ATL, ATR, A00, A01, A02, ABL, ABR, A10, A11, A12, A20, A21, A22; Matrix<F> dT, d0, dB, d1, d2; Matrix<F> S21; // Start the algorithm PartitionDownDiagonal ( A, ATL, ATR, ABL, ABR, 0 ); PartitionDown ( d, dT, dB, 0 ); while( ABR.Height() > 0 ) { RepartitionDownDiagonal ( ATL, /**/ ATR, A00, /**/ A01, A02, /*************/ /******************/ /**/ A10, /**/ A11, A12, ABL, /**/ ABR, A20, /**/ A21, A22 ); RepartitionDown ( dT, d0, /**/ /**/ d1, dB, d2 ); //--------------------------------------------------------------------// ldl::Var3Unb( orientation, A11, d1 ); Trsm( RIGHT, LOWER, orientation, UNIT, F(1), A11, A21 ); S21 = A21; DiagonalSolve( RIGHT, NORMAL, d1, A21 ); internal::TrrkNT( LOWER, orientation, F(-1), S21, A21, F(1), A22 ); //--------------------------------------------------------------------// SlidePartitionDown ( dT, d0, d1, /**/ /**/ dB, d2 ); SlidePartitionDownDiagonal ( ATL, /**/ ATR, A00, A01, /**/ A02, /**/ A10, A11, /**/ A12, /*************/ /******************/ ABL, /**/ ABR, A20, A21, /**/ A22 ); } #ifndef RELEASE PopCallStack(); #endif }
inline void TrdtrmmLVar1( Orientation orientation, DistMatrix<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 const Grid& g = L.Grid(); // Matrix views DistMatrix<F> LTL(g), LTR(g), L00(g), L01(g), L02(g), LBL(g), LBR(g), L10(g), L11(g), L12(g), L20(g), L21(g), L22(g); DistMatrix<F,MD,STAR> d1(g); // Temporary distributions DistMatrix<F,STAR,VR > L10_STAR_VR(g); DistMatrix<F,STAR,VC > S10_STAR_VC(g); DistMatrix<F,STAR,MC > S10_STAR_MC(g); DistMatrix<F,STAR,MR > L10_STAR_MR(g); DistMatrix<F,STAR,STAR> L11_STAR_STAR(g); L10_STAR_VR.AlignWith( L ); S10_STAR_VC.AlignWith( L ); S10_STAR_MC.AlignWith( L ); L10_STAR_MR.AlignWith( L ); 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 ); L10_STAR_VR = L10; S10_STAR_VC = L10_STAR_VR; S10_STAR_MC = S10_STAR_VC; DiagonalSolve( LEFT, NORMAL, d1, L10_STAR_VR, true ); L10_STAR_MR = L10_STAR_VR; LocalTrrk ( LOWER, orientation, F(1), S10_STAR_MC, L10_STAR_MR, F(1), L00 ); L11_STAR_STAR = L11; LocalTrmm ( LEFT, LOWER, orientation, UNIT, F(1), L11_STAR_STAR, L10_STAR_VR ); L10 = L10_STAR_VR; LocalTrdtrmm( orientation, LOWER, L11_STAR_STAR ); L11 = L11_STAR_STAR; //--------------------------------------------------------------------// SlidePartitionDownDiagonal ( LTL, /**/ LTR, L00, L01, /**/ L02, /**/ L10, L11, /**/ L12, /*************/ /******************/ LBL, /**/ LBR, L20, L21, /**/ L22 ); } }