Esempio n. 1
0
QDWHInfo QDWH( Matrix<F>& A, const QDWHCtrl& ctrl )
{
    EL_DEBUG_CSE
    typedef Base<F> Real;
    const Real twoEst = TwoNormEstimate( A );
    A *= 1/twoEst;

    // The one-norm of the inverse can be replaced with an estimate which is
    // a few times cheaper, e.g., via Higham and Tisseur's block algorithm
    // from "A Block Algorithm for Matrix 1-Norm Estimation, with an Application
    // to 1-Norm Pseudospectra".
    Real sMinUpper;
    Matrix<F> Y( A );
    if( A.Height() > A.Width() )
    {
        qr::ExplicitTriang( Y );
        try
        {
            TriangularInverse( UPPER, NON_UNIT, Y );
            sMinUpper = Real(1) / OneNorm( Y );
        } catch( SingularMatrixException& e ) { sMinUpper = 0; }
    }
    else
    {
        try
        {
            Inverse( Y );
            sMinUpper = Real(1) / OneNorm( Y );
        } catch( SingularMatrixException& e ) { sMinUpper = 0; }
    }

    return QDWHInner( A, sMinUpper, ctrl );
}
Esempio n. 2
0
Base<F> Norm( const Matrix<F>& A, NormType type )
{
    DEBUG_ONLY(CSE cse("Norm"))
    Base<F> norm = 0;
    switch( type )
    {
    // The following norms are rather cheap to compute
    case ENTRYWISE_ONE_NORM:
        norm = EntrywiseNorm( A, Base<F>(1) );
        break;
    case FROBENIUS_NORM: 
        norm = FrobeniusNorm( A );
        break;
    case INFINITY_NORM:
        norm = InfinityNorm( A );
        break;
    case MAX_NORM:
        norm = MaxNorm( A );
        break;
    case ONE_NORM:
        norm = OneNorm( A );
        break;
    // The following two norms make use of an SVD
    case NUCLEAR_NORM:
        norm = NuclearNorm( A );
        break;
    case TWO_NORM:
        norm = TwoNorm( A );
        break;
    }
    return norm;
}
Esempio n. 3
0
T InfinityNorm(const SparseMatrix<T>& A)
{
    // the infinity norm is the max absolute row sum; easier to transpose first
    // and return the one norm of the transpose
    SparseMatrix<T> Atranspose;
    Transpose(A, Atranspose);
    return OneNorm(Atranspose);
}
Esempio n. 4
0
Int
Newton( DistMatrix<Field>& A, const SignCtrl<Base<Field>>& ctrl )
{
    EL_DEBUG_CSE
    typedef Base<Field> Real;
    Real tol = ctrl.tol;
    if( tol == Real(0) )
        tol = A.Height()*limits::Epsilon<Real>();

    Int numIts=0;
    DistMatrix<Field> B( A.Grid() );
    DistMatrix<Field> *X=&A, *XNew=&B;
    while( numIts < ctrl.maxIts )
    {
        // Overwrite XNew with the new iterate
        NewtonStep( *X, *XNew, ctrl.scaling );

        // Use the difference in the iterates to test for convergence
        Axpy( Real(-1), *XNew, *X );
        const Real oneDiff = OneNorm( *X );
        const Real oneNew = OneNorm( *XNew );

        // Ensure that X holds the current iterate and break if possible
        ++numIts;
        std::swap( X, XNew );
        if( ctrl.progress && A.Grid().Rank() == 0 )
            cout << "after " << numIts << " Newton iter's: "
                 << "oneDiff=" << oneDiff << ", oneNew=" << oneNew
                 << ", oneDiff/oneNew=" << oneDiff/oneNew << ", tol="
                 << tol << endl;
        if( oneDiff/oneNew <= Pow(oneNew,ctrl.power)*tol )
            break;
    }
    if( X != &A )
        A = *X;
    return numIts;
}
Esempio n. 5
0
ValueInt<Base<F>> InverseFreeSignDivide( ElementalMatrix<F>& XPre )
{
    DEBUG_CSE

    DistMatrixReadWriteProxy<F,F,MC,MR> XProx( XPre );
    auto& X = XProx.Get();

    typedef Base<F> Real;
    const Grid& g = X.Grid();
    const Int n = X.Width();
    if( X.Height() != 2*n )
        LogicError("Matrix should be 2n x n");
   
    // Expose A and B, and then copy A
    auto B = X( IR(0,n  ), ALL );
    auto A = X( IR(n,2*n), ALL );
    DistMatrix<F> ACopy( A );

    // Run the inverse-free alternative to Sign
    InverseFreeSign( X );

    // Compute the pivoted QR decomp of inv(A + B) A [See LAWN91]
    // 1) B := A + B 
    // 2) [Q,R,Pi] := QRP(A)
    // 3) B := Q^H B
    // 4) [R,Q] := RQ(B)
    B += A;
    DistMatrix<F,MD,STAR> t(g);
    DistMatrix<Base<F>,MD,STAR> d(g);
    DistMatrix<Int,VR,STAR> p(g);
    QR( A, t, d, p );
    qr::ApplyQ( LEFT, ADJOINT, A, t, d, B );
    RQ( B, t, d );

    // A := Q^H A Q
    A = ACopy;
    rq::ApplyQ( LEFT, ADJOINT, B, t, d, A );
    rq::ApplyQ( RIGHT, NORMAL, B, t, d, A );

    // Return || E21 ||1 / || A ||1
    // Return || E21 ||1 / || A ||1
    ValueInt<Real> part = ComputePartition( A );
    part.value /= OneNorm(ACopy);
    return part;
}
Esempio n. 6
0
TwoNormUpperBound( const DistMatrix<F>& A )
{
#ifndef RELEASE
    CallStackEntry entry("TwoNormUpperBound");
#endif
    typedef BASE(F) R;
    const R m = A.Height();
    const R n = A.Width();

    const R maxNorm = MaxNorm( A );
    const R oneNorm = OneNorm( A );
    const R infNorm = InfinityNorm( A );

    R upperBound = std::min( Sqrt(m*n)*maxNorm, Sqrt(m)*infNorm );
    upperBound = std::min( upperBound, Sqrt(n)*oneNorm );
    upperBound = std::min( upperBound, Sqrt( oneNorm*infNorm ) );
    return upperBound;
}
Esempio n. 7
0
Base<F> InverseFreeSignDivide( Matrix<F>& X )
{
    DEBUG_CSE
    typedef Base<F> Real;
    const Int n = X.Width();
    if( X.Height() != 2*n )
        LogicError("Matrix should be 2n x n");
   
    // Expose A and B, and then copy A
    auto B = X( IR(0,n  ), ALL );
    auto A = X( IR(n,2*n), ALL );
    Matrix<F> ACopy( A );

    // Run the inverse-free alternative to Sign
    InverseFreeSign( X );

    // Compute the pivoted QR decomp of inv(A + B) A [See LAWN91]
    // 1) B := A + B 
    // 2) [Q,R,Pi] := QRP(A)
    // 3) B := Q^H B
    // 4) [R,Q] := RQ(B)
    B += A;
    Matrix<F> t;
    Matrix<Base<F>> d;
    Matrix<Int> p;
    QR( A, t, d, p );
    qr::ApplyQ( LEFT, ADJOINT, A, t, d, B );
    RQ( B, t, d );

    // A := Q^H A Q
    A = ACopy;
    rq::ApplyQ( LEFT, ADJOINT, B, t, d, A );
    rq::ApplyQ( RIGHT, NORMAL, B, t, d, A );

    // Return || E21 ||1 / || A ||1
    ValueInt<Real> part = ComputePartition( A );
    part.value /= OneNorm(ACopy);
    return part;
}
Esempio n. 8
0
inline ValueInt<BASE(F)>
QDWHDivide
( UpperOrLower uplo, DistMatrix<F>& A, DistMatrix<F>& G, bool returnQ=false )
{
    DEBUG_ONLY(CallStackEntry cse("herm_eig::QDWHDivide"))

    // G := sgn(G)
    // G := 1/2 ( G + I )
    herm_polar::QDWH( uplo, G ); 
    UpdateDiagonal( G, F(1) );
    Scale( F(1)/F(2), G );

    // Compute the pivoted QR decomposition of the spectral projection 
    const Grid& g = A.Grid();
    DistMatrix<F,MD,STAR> t(g);
    DistMatrix<Int,VR,STAR> p(g);
    elem::QR( G, t, p );

    // A := Q^H A Q
    MakeHermitian( uplo, A );
    const Base<F> oneA = OneNorm( A );
    if( returnQ )
    {
        ExpandPackedReflectors( LOWER, VERTICAL, CONJUGATED, 0, G, t );
        DistMatrix<F> B(g);
        Gemm( ADJOINT, NORMAL, F(1), G, A, B );
        Gemm( NORMAL, NORMAL, F(1), B, G, A );
    }
    else
    {
        qr::ApplyQ( LEFT, ADJOINT, G, t, A );
        qr::ApplyQ( RIGHT, NORMAL, G, t, A );
    }

    // Return || E21 ||1 / || A ||1 and the chosen rank
    auto part = ComputePartition( A );
    part.value /= oneA;
    return part;
}
Esempio n. 9
0
int InverseFreeSign( ElementalMatrix<F>& XPre, Int maxIts=100, Base<F> tau=0 )
{
    DEBUG_CSE

    DistMatrixReadWriteProxy<F,F,MC,MR> XProx( XPre );
    auto& X = XProx.Get();

    typedef Base<F> Real;
    const Grid& g = X.Grid();
    const Int n = X.Width();
    if( X.Height() != 2*n )
        LogicError("X must be 2n x n");
    // Compute the tolerance if it is unset
    if( tau == Real(0) )
        tau = n*limits::Epsilon<Real>();

    // Expose A and B in the original and temporary
    DistMatrix<F> XAlt( 2*n, n, g );
    auto B = X( IR(0,n  ), ALL );
    auto A = X( IR(n,2*n), ALL );
    auto BAlt = XAlt( IR(0,n  ), ALL );
    auto AAlt = XAlt( IR(n,2*n), ALL );

    // Flip the sign of A
    A *= -1;

    // Set up the space for explicitly computing the left half of Q
    DistMatrix<F,MD,STAR> t(g);
    DistMatrix<Base<F>,MD,STAR> d(g);
    DistMatrix<F> Q( 2*n, n, g );
    auto Q12 = Q( IR(0,n  ), ALL );
    auto Q22 = Q( IR(n,2*n), ALL );

    // Run the iterative algorithm
    Int numIts=0;
    DistMatrix<F> R(g), RLast(g);
    while( numIts < maxIts )
    {
        XAlt = X;
        QR( XAlt, t, d );
 
        // Form the left half of Q
        Zero( Q12 );
        MakeIdentity( Q22 );
        qr::ApplyQ( LEFT, NORMAL, XAlt, t, d, Q );

        // Save a copy of R
        R = BAlt;
        MakeTrapezoidal( UPPER, R );
        
        // Form the new iterate
        Gemm( ADJOINT, NORMAL, F(1), Q12, A, F(0), AAlt );
        Gemm( ADJOINT, NORMAL, F(1), Q22, B, F(0), BAlt );
        X = XAlt;

        // Use the difference in the iterates to test for convergence
        ++numIts;
        if( numIts > 1 )
        {
            const Real oneRLast = OneNorm(RLast);     
            AxpyTrapezoid( UPPER, F(-1), R, RLast );
            const Real oneRDiff = OneNorm(RLast);
            if( oneRDiff <= tau*oneRLast )
                break;
        }
        RLast = R;
    }

    // Revert the sign of A and return
    A *= -1;
    return numIts;
}
Esempio n. 10
0
   This file is part of Elemental and is under the BSD 2-Clause License, 
   which can be found in the LICENSE file in the root directory, or at 
   http://opensource.org/licenses/BSD-2-Clause
*/
#include <El.hpp>

namespace El {

template<typename F> 
Base<F> OneCondition( const Matrix<F>& A )
{
    DEBUG_ONLY(CSE cse("OneCondition"))
    typedef Base<F> Real;
    Matrix<F> B( A );
    const Real oneNorm = OneNorm( B );
    try { Inverse( B ); }
    catch( SingularMatrixException& e ) 
    { return limits::Infinity<Real>(); }
    const Real oneNormInv = OneNorm( B );
    return oneNorm*oneNormInv;
}

template<typename F> 
Base<F> OneCondition( const ElementalMatrix<F>& A )
{
    DEBUG_ONLY(CSE cse("OneCondition"))
    typedef Base<F> Real;
    DistMatrix<F> B( A );
    const Real oneNorm = OneNorm( B );
    try { Inverse( B ); }
Esempio n. 11
0
    part.value /= oneA;
    return part;
}

template<typename F>
inline ValueInt<BASE(F)>
RandomizedSignDivide
( UpperOrLower uplo, Matrix<F>& A, Matrix<F>& G, 
  bool returnQ=false, Int maxIts=1, BASE(F) relTol=0 )
{
    DEBUG_ONLY(CallStackEntry cse("herm_eig::RandomizedSignDivide"))

    typedef Base<F> Real;
    const Int n = A.Height();
    MakeHermitian( uplo, A );
    const Real oneA = OneNorm( A );
    if( relTol == Real(0) )
        relTol = 500*n*lapack::MachineEpsilon<Real>();

    // S := sgn(G)
    // S := 1/2 ( S + I )
    auto S( G );
    herm_polar::QDWH( uplo, S ); 
    UpdateDiagonal( S, F(1) );
    Scale( F(1)/F(2), S );

    ValueInt<Real> part;
    Matrix<F> V, B, t;
    Int it=0;
    while( it < maxIts )
    {
Esempio n. 12
0
#ifndef ELEM_SVD_UTIL_HPP
#define ELEM_SVD_UTIL_HPP

#include ELEM_ADJOINT_INC
#include ELEM_ONENORM_INC

namespace elem {
namespace svd {

template<typename F>
inline bool
CheckScale( DistMatrix<F>& A, BASE(F)& scale )
{
    scale = 1;
    typedef Base<F> Real;
    const Real oneNormOfA = OneNorm( A );
    const Real safeMin = lapack::MachineSafeMin<Real>();
    const Real precision = lapack::MachinePrecision<Real>();
    const Real smallNumber = safeMin/precision;
    const Real bigNumber = 1/smallNumber;
    const Real rhoMin = Sqrt(smallNumber);
    const Real rhoMax = Min( Sqrt(bigNumber), 1/Sqrt(Sqrt(safeMin)) );

    if( oneNormOfA > 0 && oneNormOfA < rhoMin )
    {
        scale = rhoMin/oneNormOfA;
        return true;
    }
    else if( oneNormOfA > rhoMax )
    {
        scale = rhoMax/oneNormOfA;