Beispiel #1
0
void HermitianSign
( UpperOrLower uplo,
  AbstractDistMatrix<Field>& APre,
  AbstractDistMatrix<Field>& NPre,
  const HermitianEigCtrl<Field>& ctrl )
{
    EL_DEBUG_CSE

    DistMatrixReadWriteProxy<Field,Field,MC,MR> AProx( APre );
    DistMatrixWriteProxy<Field,Field,MC,MR> NProx( NPre );
    auto& A = AProx.Get();
    auto& N = NProx.Get();

    // Get the EVD of A
    typedef Base<Field> Real;
    const Grid& g = A.Grid();
    DistMatrix<Real,VR,STAR> w(g);
    DistMatrix<Field> Q(g);
    auto ctrlMod( ctrl );
    ctrlMod.tridiagEigCtrl.sort = UNSORTED;
    HermitianEig( uplo, A, w, Q, ctrlMod );

    const Int n = A.Height();
    const Int numLocalEigs = w.LocalHeight();
    DistMatrix<Real,VR,STAR> wSgn(g), wAbs(g);
    wSgn.AlignWith( w );
    wAbs.AlignWith( w );
    wSgn.Resize( n, 1 );
    wAbs.Resize( n, 1 );
    for( Int iLoc=0; iLoc<numLocalEigs; ++iLoc )
    {
        const Real omega = w.GetLocal(iLoc,0);
        if( omega >= 0 )
        {
            wSgn.SetLocal(iLoc,0,Real(1));
            wAbs.SetLocal(iLoc,0,omega);
        }
        else
        {
            wSgn.SetLocal(iLoc,0,Real(-1));
            wAbs.SetLocal(iLoc,0,-omega);
        }
    }

    // Form the Hermitian matrix with the modified eigenvalues
    HermitianFromEVD( uplo, A, wSgn, Q );
    HermitianFromEVD( uplo, N, wAbs, Q );
}
Beispiel #2
0
void HermitianPseudoinverse
( UpperOrLower uplo, Matrix<F>& A, Base<F> tolerance )
{
    DEBUG_CSE
    typedef Base<F> Real;

    // Get the EVD of A
    // TODO: Use a relative eigenvalue lower bound
    Matrix<Real> w;
    Matrix<F> Z;
    HermitianEig( uplo, A, w, Z );

    if( tolerance == Real(0) )
    {
        // Set the tolerance equal to n ||A||_2 eps
        const Int n = Z.Height();
        const Real eps = limits::Epsilon<Real>();
        const Real twoNorm = MaxNorm( w );
        tolerance = n*twoNorm*eps;
    }
    // Invert above the tolerance
    auto omegaMap = 
      [=]( Real omega ) { return ( omega < tolerance ? Real(0) : 1/omega ); };
    EntrywiseMap( w, function<Real(Real)>(omegaMap) );

    // Form the pseudoinverse
    HermitianFromEVD( uplo, A, w, Z );
}
Beispiel #3
0
void HermitianSign
( UpperOrLower uplo, Matrix<Field>& A, const HermitianEigCtrl<Field>& ctrl )
{
    EL_DEBUG_CSE
    typedef Base<Field> Real;

    // Get the EVD of A
    Matrix<Real> w;
    Matrix<Field> Q;
    auto ctrlMod( ctrl );
    ctrlMod.tridiagEigCtrl.sort = UNSORTED;
    HermitianEig( uplo, A, w, Q, ctrlMod );

    const Int n = A.Height();
    for( Int i=0; i<n; ++i )
    {
        const Real omega = w(i);
        if( omega >= 0 )
            w(i) = Real(1);
        else
            w(i) = Real(-1);
    }

    // Reform the Hermitian matrix with the modified eigenvalues
    HermitianFromEVD( uplo, A, w, Q );
}
Beispiel #4
0
void HermitianPseudoinverse
( UpperOrLower uplo, ElementalMatrix<F>& APre, Base<F> tolerance )
{
    DEBUG_CSE
    typedef Base<F> Real;

    DistMatrixReadWriteProxy<F,F,MC,MR> AProx( APre );
    auto& A = AProx.Get();
    const Grid& g = A.Grid();

    // Get the EVD of A
    // TODO: Use a relative eigenvalue lower-bound
    DistMatrix<Real,VR,STAR> w(g);
    DistMatrix<F> Z(g);
    HermitianEig( uplo, A, w, Z );

    if( tolerance == Real(0) )
    {
        // Set the tolerance equal to n ||A||_2 eps
        const Int n = Z.Height();
        const Real eps = limits::Epsilon<Real>();
        const Real twoNorm = MaxNorm( w );
        tolerance = n*twoNorm*eps;
    }
    // Invert above the tolerance
    auto omegaMap = 
      [=]( Real omega ) { return ( omega < tolerance ? Real(0) : 1/omega ); };
    EntrywiseMap( w, function<Real(Real)>(omegaMap) );

    // Form the pseudoinverse
    HermitianFromEVD( uplo, A, w, Z );
}
Beispiel #5
0
void HermitianSign
( UpperOrLower uplo,
  ElementalMatrix<F>& APre, 
  const HermitianEigCtrl<F>& ctrl )
{
    DEBUG_CSE

    DistMatrixReadWriteProxy<F,F,MC,MR> AProx( APre );
    auto& A = AProx.Get();

    // Get the EVD of A
    typedef Base<F> Real;
    const Grid& g = A.Grid();
    DistMatrix<Real,VR,STAR> w(g);
    DistMatrix<F> Q(g);
    auto ctrlMod( ctrl );
    ctrlMod.tridiagEigCtrl.sort = UNSORTED;
    HermitianEig( uplo, A, w, Q, ctrlMod );

    const Int numLocalEigs = w.LocalHeight();
    for( Int iLoc=0; iLoc<numLocalEigs; ++iLoc )
    {
        const Real omega = w.GetLocal(iLoc,0);
        if( omega >= 0 )
            w.SetLocal(iLoc,0,Real(1));
        else
            w.SetLocal(iLoc,0,Real(-1));
    }

    // Reform the Hermitian matrix with the modified eigenvalues
    HermitianFromEVD( uplo, A, w, Q );
}
inline Matrix<F>
HermitianFromEVD
( UpperOrLower uplo,
  const Matrix<BASE(F)>& w,
  const Matrix<F>& Z )
{
    Matrix<F> A;
    HermitianFromEVD( uplo, A, w, Z );
    return A;
}
Beispiel #7
0
void HermitianSign
( UpperOrLower uplo,
  Matrix<Field>& A,
  Matrix<Field>& N,
  const HermitianEigCtrl<Field>& ctrl )
{
    EL_DEBUG_CSE
    typedef Base<Field> Real;

    // Get the EVD of A
    Matrix<Real> w;
    Matrix<Field> Q;
    auto ctrlMod( ctrl );
    ctrlMod.tridiagEigCtrl.sort = UNSORTED;
    HermitianEig( uplo, A, w, Q, ctrlMod );

    const Int n = A.Height();
    Matrix<Real> wSgn( n, 1 ), wAbs( n, 1 );
    for( Int i=0; i<n; ++i )
    {
        const Real omega = w(i);
        if( omega >= 0 )
        {
            wSgn(i) = Real(1);
            wAbs(i) = omega;
        }
        else
        {
            wSgn(i) = Real(-1);
            wAbs(i) = -omega;
        }
    }

    // Form the Hermitian matrices with modified eigenvalues
    HermitianFromEVD( uplo, A, wSgn, Q );
    HermitianFromEVD( uplo, N, wAbs, Q );
}
Beispiel #8
0
void SVD( Matrix<F>& A, Matrix<F>& P )
{
    DEBUG_CSE
    typedef Base<F> Real;

    // Get the SVD of A
    Matrix<Real> s;
    Matrix<F> U, V;
    SVDCtrl<Real> ctrl;
    ctrl.overwrite = true;
    El::SVD( A, U, s, V, ctrl );

    // Form Q := U V^H in A
    Gemm( NORMAL, ADJOINT, F(1), U, V, A );

    // Form P := V Sigma V^H in P
    HermitianFromEVD( LOWER, P, s, V );
}
Beispiel #9
0
void SVD( ElementalMatrix<F>& APre, ElementalMatrix<F>& PPre )
{
    DEBUG_CSE
    typedef Base<F> Real;

    DistMatrixReadWriteProxy<F,F,MC,MR> AProx( APre );
    DistMatrixWriteProxy<F,F,MC,MR> PProx( PPre );
    auto& A = AProx.Get();
    auto& P = PProx.Get();
    const Grid& g = A.Grid();

    // Get the SVD of A
    DistMatrix<Real,VR,STAR> s(g);
    DistMatrix<F> U(g), V(g);
    SVDCtrl<Real> ctrl;
    ctrl.overwrite = true;
    El::SVD( A, U, s, V, ctrl );

    // Form Q := U V^H in A
    Gemm( NORMAL, ADJOINT, F(1), U, V, A );

    // Form P := V Sigma V^H in P
    HermitianFromEVD( LOWER, P, s, V );
}