inline typename Base<F>::type SymmetricSchattenNorm ( UpperOrLower uplo, const DistMatrix<F,U,V>& A, typename Base<F>::type p ) { #ifndef RELEASE PushCallStack("SymmetricSchattenNorm"); #endif typedef typename Base<F>::type R; DistMatrix<F> B( A ); DistMatrix<R,VR,STAR> s( A.Grid() ); MakeSymmetric( uplo, B ); SVD( B, s ); // TODO: Think of how to make this more stable const int kLocal = s.LocalHeight(); R localSum = 0; for( int j=0; j<kLocal; ++j ) localSum += Pow( s.GetLocal(j,0), p ); R sum; mpi::AllReduce( &localSum, &sum, 1, mpi::SUM, A.Grid().VRComm() ); const R norm = Pow( sum, 1/p ); #ifndef RELEASE PopCallStack(); #endif return norm; }
Base<F> SymmetricTwoNorm( UpperOrLower uplo, const AbstractDistMatrix<F>& A ) { DEBUG_ONLY(CSE cse("SymmetricTwoNorm")) DistMatrix<F> B( A ); DistMatrix<Base<F>,VR,STAR> s( A.Grid() ); MakeSymmetric( uplo, B ); SVD( B, s ); return MaxNorm( s ); }
Base<F> SymmetricTwoNorm( UpperOrLower uplo, const Matrix<F>& A ) { DEBUG_ONLY(CSE cse("SymmetricTwoNorm")) Matrix<F> B( A ); Matrix<Base<F>> s; MakeSymmetric( uplo, B ); SVD( B, s ); return MaxNorm( s ); }
void QuasiDiagonalSolve ( LeftOrRight side, UpperOrLower uplo, const Matrix<FMain>& d, const Matrix<F>& dSub, Matrix<F>& X, bool conjugated ) { DEBUG_CSE const Int m = X.Height(); const Int n = X.Width(); Matrix<F> D( 2, 2 ); if( side == LEFT && uplo == LOWER ) { if( m == 0 ) return; DEBUG_ONLY( if( d.Height() != m ) LogicError ("d was the wrong size: m=",m,",n=",n,", d ~ ", d.Height()," x ",d.Width()); if( dSub.Height() != m-1 ) LogicError ("dSub was the wrong size: m=",m,",n=",n,", dSub ~ ", dSub.Height()," x ",dSub.Width()); ) Int i=0; while( i < m ) { Int nb; if( i < m-1 && Abs(dSub.Get(i,0)) > 0 ) nb = 2; else nb = 1; auto XRow = X( IR(i,i+nb), IR(0,n) ); if( nb == 1 ) { Scale( F(1)/d.Get(i,0), XRow ); } else { D.Set(0,0,d.Get(i,0)); D.Set(1,1,d.Get(i+1,0)); D.Set(1,0,dSub.Get(i,0)); Symmetric2x2Inv( LOWER, D, conjugated ); MakeSymmetric( LOWER, D, conjugated ); Transform2x2Rows( D, X, i, i+1 ); } i += nb; } }
Base<F> SymmetricTwoNorm( UpperOrLower uplo, const ElementalMatrix<F>& A ) { DEBUG_ONLY(CSE cse("SymmetricTwoNorm")) DistMatrix<F> B( A ); DistMatrix<Base<F>,VR,STAR> s( A.Grid() ); MakeSymmetric( uplo, B ); SVDCtrl<Base<F>> ctrl; ctrl.overwrite = true; SVD( B, s, ctrl ); return MaxNorm( s ); }
Base<F> SymmetricTwoNorm( UpperOrLower uplo, const Matrix<F>& A ) { DEBUG_ONLY(CSE cse("SymmetricTwoNorm")) Matrix<F> B( A ); Matrix<Base<F>> s; MakeSymmetric( uplo, B ); SVDCtrl<Base<F>> ctrl; ctrl.overwrite = true; SVD( B, s, ctrl ); return MaxNorm( s ); }
inline void MakeHermitian( UpperOrLower uplo, DistMatrix<T>& A ) { #ifndef RELEASE PushCallStack("MakeHermitian"); #endif MakeSymmetric( uplo, A, true ); #ifndef RELEASE PopCallStack(); #endif }
SymmetricTwoNorm( UpperOrLower uplo, const DistMatrix<F,U,V>& A ) { #ifndef RELEASE CallStackEntry entry("SymmetricTwoNorm"); #endif typedef BASE(F) R; DistMatrix<F,U,V> B( A ); DistMatrix<R,VR,STAR> s( A.Grid() ); MakeSymmetric( uplo, B ); SVD( B, s ); return MaxNorm( s ); }
SymmetricTwoNorm( UpperOrLower uplo, const Matrix<F>& A ) { #ifndef RELEASE CallStackEntry entry("SymmetricTwoNorm"); #endif typedef BASE(F) R; Matrix<F> B( A ); Matrix<R> s; MakeSymmetric( uplo, B ); SVD( B, s ); return MaxNorm( s ); }
inline typename Base<F>::type SymmetricSchattenNorm ( UpperOrLower uplo, const Matrix<F>& A, typename Base<F>::type p ) { #ifndef RELEASE PushCallStack("SymmetricSchattenNorm"); #endif typedef typename Base<F>::type R; Matrix<F> B( A ); Matrix<R> s; MakeSymmetric( uplo, B ); SVD( B, s ); // TODO: Think of how to make this more stable const int k = s.Height(); R sum = 0; for( int j=0; j<k; ++j ) sum += Pow( s.Get(j,0), p ); const R norm = Pow( sum, 1/p ); #ifndef RELEASE PopCallStack(); #endif return norm; }
void QuasiDiagonalScale ( LeftOrRight side, UpperOrLower uplo, const Matrix<FMain>& d, const Matrix<F>& dSub, Matrix<F>& X, bool conjugated ) { DEBUG_CSE const Int m = X.Height(); const Int n = X.Width(); Matrix<F> D( 2, 2 ); if( side == LEFT && uplo == LOWER ) { Int i=0; while( i < m ) { Int nb; if( i < m-1 && Abs(dSub.Get(i,0)) > 0 ) nb = 2; else nb = 1; if( nb == 1 ) { auto xRow = View( X, i, 0, nb, n ); Scale( d.Get(i,0), xRow ); } else { D.Set(0,0,d.Get(i,0)); D.Set(1,1,d.Get(i+1,0)); D.Set(1,0,dSub.Get(i,0)); MakeSymmetric( LOWER, D, conjugated ); Transform2x2Rows( D, X, i, i+1 ); } i += nb; } } else if( side == RIGHT && uplo == LOWER ) { Int j=0; while( j < n ) { Int nb; if( j < n-1 && Abs(dSub.Get(j,0)) > 0 ) nb = 2; else nb = 1; if( nb == 1 ) { auto xCol = View( X, 0, j, m, nb ); Scale( d.Get(j,0), xCol ); } else { D.Set(0,0,d.Get(j,0)); D.Set(1,1,d.Get(j+1,0)); D.Set(1,0,dSub.Get(j,0)); MakeSymmetric( LOWER, D, conjugated ); Transform2x2Cols( D, X, j, j+1 ); } j += nb; } } else LogicError("This option not yet supported"); }
void MakeHermitian( UpperOrLower uplo, DistSparseMatrix<T>& A ) { DEBUG_ONLY(CallStackEntry cse("MakeHermitian")) MakeSymmetric( uplo, A, true ); }