Base<F> HermitianNorm( UpperOrLower uplo, const Matrix<F>& A, NormType type ) { DEBUG_ONLY(CSE cse("HermitianNorm")) Base<F> norm = 0; switch( type ) { // The following norms are rather cheap to compute case FROBENIUS_NORM: norm = HermitianFrobeniusNorm( uplo, A ); break; case ENTRYWISE_ONE_NORM: norm = HermitianEntrywiseNorm( uplo, A, Base<F>(1) ); break; case INFINITY_NORM: norm = HermitianInfinityNorm( uplo, A ); break; case MAX_NORM: norm = HermitianMaxNorm( uplo, A ); break; case ONE_NORM: norm = HermitianOneNorm( uplo, A ); break; // The following norms make use of an SVD case NUCLEAR_NORM: norm = HermitianNuclearNorm( uplo, A ); break; case TWO_NORM: norm = HermitianTwoNorm( uplo, A ); break; } return norm; }
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 ); }
bool CheckScale( UpperOrLower uplo, DistMatrix<F>& A, Base<F>& scale ) { typedef Base<F> Real; scale = 1; const Real maxNormOfA = HermitianMaxNorm( uplo, A ); const Real underflowThreshold = lapack::MachineUnderflowThreshold<Real>(); const Real overflowThreshold = lapack::MachineOverflowThreshold<Real>(); if( maxNormOfA > 0 && maxNormOfA < underflowThreshold ) { scale = underflowThreshold / maxNormOfA; return true; } else if( maxNormOfA > overflowThreshold ) { scale = overflowThreshold / maxNormOfA; return true; } else return false; }