示例#1
0
MaxCondition( const DistMatrix<F,U,V>& A )
{
#ifndef RELEASE
    CallStackEntry entry("MaxCondition");
#endif
    typedef BASE(F) Real;
    DistMatrix<F> B( A );
    const Real maxNorm = MaxNorm( B );
    try { Inverse( B ); }
    catch( SingularMatrixException& e ) 
    { return std::numeric_limits<Real>::infinity(); }
    const Real maxNormInv = MaxNorm( B );
    return maxNorm*maxNormInv;
}
示例#2
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 );
}
pair<Base<F>,Base<F>>
HermitianHelper( const DistSparseMatrix<F>& A, Int basisSize )
{
    typedef Base<F> Real;
    Grid grid( A.Comm() );

    DistMatrix<Real,STAR,STAR> T(grid);
    Lanczos( A, T, basisSize );
    const Int k = T.Height();
    if( k == 0 )
        return pair<Real,Real>(0,0);

    auto d = GetDiagonal( T.Matrix() );
    auto dSub = GetDiagonal( T.Matrix(), -1 );

    Matrix<Real> w;
    HermitianTridiagEig( d, dSub, w );

    pair<Real,Real> extremal;
    extremal.second = MaxNorm(w);
    extremal.first = extremal.second;
    for( Int i=0; i<k; ++i )
        extremal.first = Min(extremal.first,Abs(w.Get(i,0)));

    return extremal;
}
示例#4
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 );
}
示例#5
0
文件: Norm.cpp 项目: birm/Elemental
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;
}
示例#6
0
pair<Base<F>,Base<F>>
HermitianExtremalSingValEst( const SparseMatrix<F>& A, Int basisSize )
{
    EL_DEBUG_CSE
    typedef Base<F> Real;
    Matrix<Real> T;
    Lanczos( A, T, basisSize );
    const Int k = T.Height();
    if( k == 0 )
        return pair<Real,Real>(0,0);

    Matrix<Real> d, dSub;
    d = GetDiagonal( T );
    dSub = GetDiagonal( T, -1 );
    
    Matrix<Real> w;
    HermitianTridiagEig( d, dSub, w );
    
    pair<Real,Real> extremal;
    extremal.second = MaxNorm(w);
    extremal.first = extremal.second;
    for( Int i=0; i<k; ++i )
        extremal.first = Min(extremal.first,Abs(w(i)));
    return extremal;
}
示例#7
0
inline void
HermitianSign( UpperOrLower uplo, Matrix<F>& A )
{
#ifndef RELEASE
    CallStackEntry entry("HermitianSign");
#endif
    typedef BASE(F) R;

    // Get the EVD of A
    Matrix<R> w;
    Matrix<F> Z;
    HermitianEig( uplo, A, w, Z );

    // Compute the two-norm of A as the maximum absolute value of its eigvals
    const R twoNorm = MaxNorm( w );

    // Set the tolerance equal to n ||A||_2 eps, and invert values above it
    const int n = A.Height();
    const R eps = lapack::MachineEpsilon<R>();
    const R tolerance = n*twoNorm*eps;
    for( int i=0; i<n; ++i )
    {
        const R omega = w.Get(i,0);
        if( Abs(omega) < tolerance )
            w.Set(i,0,0);
        else if( omega > 0 )
            w.Set(i,0,R(1));
        else
            w.Set(i,0,R(-1));
    }

    // Reform the Hermitian matrix with the modified eigenvalues
    hermitian_function::ReformHermitianMatrix( uplo, A, w, Z );
}
示例#8
0
文件: Two.cpp 项目: birm/Elemental
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 );
}
示例#9
0
文件: Two.cpp 项目: birm/Elemental
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 );
}
示例#10
0
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 );
}
示例#11
0
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 );
}
示例#12
0
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 );
}
示例#13
0
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 );
}
示例#14
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;
}
inline void
HermitianPseudoinverse
( UpperOrLower uplo, DistMatrix<F>& A )
{
#ifndef RELEASE
    PushCallStack("HermitianPseudoinverse");
#endif
    typedef typename Base<F>::type R;

    // Get the EVD of A
    const Grid& g = A.Grid();
    DistMatrix<R,VR,STAR> w(g);
    DistMatrix<F> Z(g);
    HermitianEig( uplo, A, w, Z );

    // Compute the two-norm of A as the maximum absolute value of its eigvals
    const R twoNorm = MaxNorm( w );

    // Set the tolerance equal to n ||A||_2 eps, and invert values above it
    const int n = A.Height();
    const R eps = lapack::MachineEpsilon<R>();
    const R tolerance = n*twoNorm*eps;
    const int numLocalEigs = w.LocalHeight();
    for( int iLocal=0; iLocal<numLocalEigs; ++iLocal )
    {
        const R omega = w.GetLocal(iLocal,0);
        if( Abs(omega) < tolerance )
            w.SetLocal(iLocal,0,0);
        else
            w.SetLocal(iLocal,0,1/omega);
    }

    // Form the pseudoinverse
    hermitian_function::ReformHermitianMatrix( uplo, A, w, Z );
#ifndef RELEASE
    PopCallStack();
#endif
}
示例#16
0
namespace El {
namespace kmeans {

template<typename F>
void AssignClusters
( const Matrix<F>& D, Matrix<Int>& cluster, Matrix<Base<F>>& dist )
{
    DEBUG_ONLY(CallStackEntry cse("kmeans::AssignClusters"))
    typedef Base<F> Real;
    const Int numPoints = D.Height();
    const Int numClusters = D.Width();
    cluster.Resize( numPoints, 1 );
    dist.Resize( numPoints, 1 );

    const Base<F> maxNorm = MaxNorm( D );
    vector<ValueInt<Real>> choices(numPoints);
    for( Int i=0; i<numPoints; ++i )
    {
        ValueInt<Real> choice;
        choice.value = 2*maxNorm;
        choice.index = -1;

        for( Int j=0; j<numClusters; ++j )
        {
            const Real rho = RealPart(D.Get(i,j));
            if( rho < choice.value ) 
            {
                choice.value = rho;
                choice.index = j;
            }
int
main( int argc, char* argv[] )
{
    El::Environment env( argc, argv );

    try
    {
        El::Int gridHeight =
          El::Input("--gridHeight","process grid height",0);
        const bool colMajor =
          El::Input("--colMajor","column-major ordering?",true);
        const El::Int matType =
          El::Input("--matType","0:uniform,\n"
                                "1:Haar,\n"
                                "2:Lotkin,\n"
                                "3:Grcar,\n"
                                "4:FoxLi,\n"
                                "5:HelmholtzPML1D,\n"
                                "6:HelmholtzPML2D,\n"
                                "7:TrefethenEmbree,\n"
                                "8:Bull's head,\n"
                                "9:Triangle,\n"
                                "10:Whale,\n"
                                "11:UniformHelmholtzGreen's,\n"
                                "12:HatanoNelson,\n"
                                "13:EhrenfestDecay,\n"
                                "14:RiffleDecay\n"
                                "15:Jordan\n",4);
        const El::Int normInt = El::Input("--norm","0:two norm,1:one norm",0);
        const El::Int n = El::Input("--size","height of matrix",100);
        const El::Int nbAlg = El::Input("--nbAlg","algorithmic blocksize",96);

        // QR algorithm options
        const El::Int nbDist =
          El::Input("--nbDist","distribution blocksize",32);

        // Spectral Divide and Conquer options
        const bool sdc = El::Input("--sdc","use Spectral D&C?",false);
        const El::Int cutoff = El::Input("--cutoff","problem size for QR",256);
        const El::Int maxInnerIts = El::Input("--maxInnerIts","SDC limit",2);
        const El::Int maxOuterIts = El::Input("--maxOuterIts","SDC limit",10);
        const bool random = El::Input("--random","Random RRQR in SDC",true);
        const double sdcTol = El::Input("--sdcTol","Rel. tol. for SDC",1e-6);
        const double spreadFactor =
          El::Input("--spreadFactor","median pert.",1e-6);
        const double signTol =
          El::Input("--signTol","Sign tolerance for SDC",1e-9);

        const double realCenter = El::Input("--realCenter","real center",0.);
        const double imagCenter = El::Input("--imagCenter","imag center",0.);
        double realWidth = El::Input("--realWidth","x width of image",0.);
        double imagWidth = El::Input("--imagWidth","y width of image",0.);
        const El::Int numReal = El::Input("--numReal","num real chunks",2);
        const El::Int numImag = El::Input("--numImag","num imag chunks",2);
        const El::Int realSize =
          El::Input("--realSize","number of x samples",100);
        const El::Int imagSize =
          El::Input("--imagSize","number of y samples",100);
        const bool arnoldi = El::Input("--arnoldi","use Arnoldi?",true);
        const El::Int basisSize =
          El::Input("--basisSize","num basis vectors",10);
        const El::Int maxIts =
          El::Input("--maxIts","maximum pseudospec iter's",200);
        const double psTol =
          El::Input("--psTol","tolerance for pseudospectra",1e-6);
        // Uniform options
        const double uniformRealCenter =
          El::Input("--uniformRealCenter","real center of uniform dist",0.);
        const double uniformImagCenter =
          El::Input("--uniformImagCenter","imag center of uniform dist",0.);
        const double uniformRadius =
          El::Input("--uniformRadius","radius of uniform dist",1.);
        // Grcar options
        const El::Int numBands =
          El::Input("--numBands","num bands for Grcar",3);
        // Fox-Li options
        const double omega =
          El::Input("--omega","frequency for Fox-Li/Helm",16*M_PI);
        // Helmholtz-PML options [also uses omega from Fox-Li]
        const El::Int mx =
          El::Input("--mx","number of x points for HelmholtzPML",30);
        const El::Int my =
          El::Input("--my","number of y points for HelmholtzPML",30);
        const El::Int numPmlPoints =
          El::Input("--numPml","num PML points for Helm",5);
        const double sigma = El::Input("--sigma","PML amplitude",1.5);
        const double pmlExp =
          El::Input("--pmlExp","PML takeoff exponent",3.);
        // Uniform Helmholtz Green's options
        const double lambda =
          El::Input("--lambda","wavelength of U.H.Green's",0.1);
        // Hatano-Nelson options
        const double gHatano =
          El::Input("--gHatano","g in Hatano-Nelson",0.5);
        const bool periodic =
          El::Input("--periodic","periodic HatanoNelson?",true);
        // Input/Output options
        const bool progress = El::Input("--progress","print progress?",true);
        const bool deflate = El::Input("--deflate","deflate?",true);
        const bool display = El::Input("--display","display matrices?",false);
        const bool write = El::Input("--write","write matrices?",false);
        const bool saveSchur =
          El::Input("--saveSchur","save Schur factor?",true);
        const El::Int numSaveFreq =
          El::Input("--numSaveFreq","numerical save frequency",-1);
        const El::Int imgSaveFreq =
          El::Input("--imgSaveFreq","image save frequency",-1);
        const El::Int imgDispFreq =
          El::Input("--imgDispFreq","image display frequency",-1);
        const std::string numBase =
          El::Input("--numBase","numerical save basename",std::string("num"));
        const std::string imgBase =
          El::Input("--imgBase","image save basename",std::string("img"));
        const El::Int numFormatInt =
          El::Input("--numFormat","numerical format",2);
        const El::Int imgFormatInt =
          El::Input("--imgFormat","image format",8);
        const El::Int colorMapInt =
          El::Input("--colorMap","color map",0);
        const bool itCounts =
          El::Input("--itCounts","display iter. counts?",true);
        El::ProcessInput();
        El::PrintInputReport();

        El::mpi::Comm comm = El::mpi::COMM_WORLD;
        if( gridHeight == 0 )
            gridHeight = El::Grid::DefaultHeight( El::mpi::Size(comm) );
        const El::GridOrder order = colMajor ? El::COLUMN_MAJOR : El::ROW_MAJOR;
        const El::Grid grid( comm, gridHeight, order );
        El::SetBlocksize( nbAlg );
        if( normInt < 0 || normInt > 1 )
            El::LogicError("Invalid pseudospec norm type");
        if( numFormatInt < 1 || numFormatInt >= El::FileFormat_MAX )
            El::LogicError
            ("Invalid numerical format integer, should be in [1,",
             El::FileFormat_MAX,")");
        if( imgFormatInt < 1 || imgFormatInt >= El::FileFormat_MAX )
            El::LogicError
            ("Invalid image format integer, should be in [1,",
             El::FileFormat_MAX,")");

        const auto psNorm    = static_cast<El::PseudospecNorm>(normInt);
        const auto numFormat = static_cast<El::FileFormat>(numFormatInt);
        const auto imgFormat = static_cast<El::FileFormat>(imgFormatInt);
        const auto colorMap  = static_cast<El::ColorMap>(colorMapInt);
        El::SetColorMap( colorMap );
        const El::Complex<double>
          center(realCenter,imagCenter),
          uniformCenter(uniformRealCenter,uniformImagCenter);

        bool isReal = true;
        std::string matName;
        El::DistMatrix<double> AReal(grid);
        El::DistMatrix<El::Complex<double>> ACpx(grid);
        switch( matType )
        {
        case 0: matName="uniform";
                El::Uniform( ACpx, n, n, uniformCenter, uniformRadius );
                isReal = false;
                break;
        case 1: matName="Haar";
                El::Haar( ACpx, n );
                isReal = false;
                break;
        case 2: matName="Lotkin";
                El::Lotkin( AReal, n );
                isReal = true;
                break;
        case 3: matName="Grcar";
                El::Grcar( AReal, n, numBands );
                isReal = true;
                break;
        case 4: matName="FoxLi";
                El::FoxLi( ACpx, n, omega );
                isReal = false;
                break;
        case 5: matName="HelmholtzPML";
                El::HelmholtzPML
                ( ACpx, n, El::Complex<double>(omega), numPmlPoints, sigma,
                  pmlExp );
                isReal = false;
                break;
        case 6: matName="HelmholtzPML2D";
                El::HelmholtzPML
                ( ACpx, mx, my, El::Complex<double>(omega), numPmlPoints, sigma,
                  pmlExp );
                isReal = false;
                break;
        case 7: matName="TrefethenEmbree";
                El::TrefethenEmbree( ACpx, n );
                isReal = false;
                break;
        case 8: matName="BullsHead";
                El::BullsHead( ACpx, n );
                isReal = false;
                break;
        case 9: matName="Triangle";
                El::Triangle( AReal, n );
                isReal = true;
                break;
        case 10: matName="Whale";
                 El::Whale( ACpx, n );
                 isReal = false;
                 break;
        case 11: matName="UniformHelmholtzGreens";
                 El::UniformHelmholtzGreens( ACpx, n, lambda );
                 isReal = false;
                 break;
        case 12: matName="HatanoNelson";
                 El::HatanoNelson
                 ( AReal, n, realCenter, uniformRadius, gHatano, periodic );
                 isReal = true;
                 break;
        case 13: matName="EhrenfestDecay";
                 // Force the complex matrix to allow for one-norm pseudospectra
                 El::EhrenfestDecay( ACpx, n );
                 isReal = false;
                 break;
        case 14: matName="RiffleDecay";
                 // Force the complex matrix to allow for one-norm pseudospectra
                 El::RiffleDecay( ACpx, n );
                 isReal = false;
                 break;
        case 15: matName="Jordan";
                 El::Jordan( AReal, n, 0. );
                 isReal = true;
                 break;
        default: El::LogicError("Invalid matrix type");
        }
        if( display )
        {
            if( isReal )
                El::Display( AReal, "A" );
            else
                El::Display( ACpx, "A" );
        }
        if( write )
        {
            if( isReal )
            {
                El::Write( AReal, "A", numFormat );
                El::Write( AReal, "A", imgFormat );
            }
            else
            {
                El::Write( ACpx, "A", numFormat );
                El::Write( ACpx, "A", imgFormat );
            }
        }

        // Begin by computing the Schur decomposition
        El::Timer timer;
        El::DistMatrix<El::Complex<double>> w(grid);
        El::mpi::Barrier( comm );
        const bool formATR = true;
        El::DistMatrix<double> QReal(grid);
        El::DistMatrix<El::Complex<double>> QCpx(grid);
        El::SchurCtrl<double> ctrl;
        ctrl.hessSchurCtrl.fullTriangle = formATR;
        ctrl.hessSchurCtrl.blockHeight = nbDist;
        ctrl.hessSchurCtrl.scalapack = false;
        ctrl.useSDC = sdc;
        // Spectral D&C options (only relevant if 'sdc' is true)
        ctrl.sdcCtrl.cutoff = cutoff;
        ctrl.sdcCtrl.maxInnerIts = maxInnerIts;
        ctrl.sdcCtrl.maxOuterIts = maxOuterIts;
        ctrl.sdcCtrl.tol = sdcTol;
        ctrl.sdcCtrl.spreadFactor = spreadFactor;
        ctrl.sdcCtrl.random = random;
        ctrl.sdcCtrl.progress = progress;
        ctrl.sdcCtrl.signCtrl.tol = signTol;
        ctrl.sdcCtrl.signCtrl.progress = progress;

        timer.Start();
        if( isReal )
        {
            if( psNorm == El::PS_TWO_NORM )
                El::Schur( AReal, w, ctrl );
            else
                El::Schur( AReal, w, QReal, ctrl );
        }
        else
        {
            if( psNorm == El::PS_TWO_NORM )
                El::Schur( ACpx, w, ctrl );
            else
                El::Schur( ACpx, w, QCpx, ctrl );
        }
        El::mpi::Barrier( comm );
        const double schurTime = timer.Stop();
        if( El::mpi::Rank(comm) == 0 )
            El::Output("Schur decomposition took ",schurTime," seconds");

        if( saveSchur )
        {
            if( El::mpi::Rank(comm) == 0 )
                El::Output("Writing Schur decomposition to file...");
            timer.Start();
            if( isReal )
            {
                auto schurTitle =
                  El::BuildString
                  (matName,"_",AReal.ColStride(),"x",AReal.RowStride(),
                   "_",AReal.DistRank());
                El::Write( AReal.LockedMatrix(), schurTitle, El::BINARY );
                if( psNorm == El::PS_ONE_NORM )
                {
                    auto QTitle =
                      El::BuildString
                      (matName,"_Q_",QReal.ColStride(),"x",QReal.RowStride(),
                       "_",QReal.DistRank());
                    El::Write( QReal.LockedMatrix(), QTitle, El::BINARY );
                }
            }
            else
            {
                auto schurTitle =
                  El::BuildString
                  (matName,"_",ACpx.ColStride(),"x",ACpx.RowStride(),
                   "_",ACpx.DistRank());
                El::Write( ACpx.LockedMatrix(), schurTitle, El::BINARY );
                if( psNorm == El::PS_ONE_NORM )
                {
                    auto QTitle =
                      El::BuildString
                      (matName,"_Q_",QCpx.ColStride(),"x",QCpx.RowStride(),
                       "_",QCpx.DistRank());
                    El::Write( QCpx.LockedMatrix(), QTitle, El::BINARY );
                }
            }
            El::mpi::Barrier( comm );
            const double saveSchurTime = timer.Stop();
            if( El::mpi::Rank(comm) == 0 )
                El::Output("Saving took ",saveSchurTime," seconds");
        }

        // Find a window if none is specified
        if( realWidth == 0. || imagWidth == 0. )
        {
            const double radius = El::MaxNorm( w );
            const double oneNorm =
              isReal ? El::OneNorm(AReal) : El::OneNorm(ACpx);
            double width;
            if( oneNorm == 0. && radius == 0. )
            {
                width = 1;
                if( El::mpi::Rank(comm) == 0 )
                    El::Output("Setting width to 1 to handle zero matrix");
            }
            else if( radius >= 0.2*oneNorm )
            {
                width = 2.5*radius;
                if( El::mpi::Rank(comm) == 0 )
                    El::Output
                    ("Setting width to ",width,
                     " based on the spectral radius, ",radius);
            }
            else
            {
                width = 0.8*oneNorm;
                if( El::mpi::Rank(comm) == 0 )
                    El::Output
                    ("Setting width to ",width," based on the one norm, ",
                     oneNorm);
            }
            realWidth = width;
            imagWidth = width;
        }

        El::PseudospecCtrl<double> psCtrl;
        psCtrl.norm = psNorm;
        psCtrl.schur = true;
        psCtrl.maxIts = maxIts;
        psCtrl.tol = psTol;
        psCtrl.deflate = deflate;
        psCtrl.arnoldi = arnoldi;
        psCtrl.basisSize = basisSize;
        psCtrl.progress = progress;
        psCtrl.snapCtrl.imgSaveFreq = imgSaveFreq;
        psCtrl.snapCtrl.numSaveFreq = numSaveFreq;
        psCtrl.snapCtrl.imgDispFreq = imgDispFreq;
        psCtrl.snapCtrl.imgFormat = imgFormat;
        psCtrl.snapCtrl.numFormat = numFormat;
        psCtrl.snapCtrl.itCounts = itCounts;

        // Visualize/write the pseudospectra within each window
        El::DistMatrix<double> invNormMap(grid);
        El::DistMatrix<El::Int> itCountMap(grid);
        const El::Int xBlock = realSize / numReal;
        const El::Int yBlock = imagSize / numImag;
        const El::Int xLeftover = realSize - (numReal-1)*xBlock;
        const El::Int yLeftover = imagSize - (numImag-1)*yBlock;
        const double realStep = realWidth/realSize;
        const double imagStep = imagWidth/imagSize;
        const El::Complex<double> corner =
          center - El::Complex<double>(realWidth/2,imagWidth/2);
        for( El::Int realChunk=0; realChunk<numReal; ++realChunk )
        {
            const El::Int realChunkSize =
              ( realChunk==numReal-1 ? xLeftover : xBlock );
            const double realChunkWidth = realStep*realChunkSize;
            for( El::Int imagChunk=0; imagChunk<numImag; ++imagChunk )
            {
                auto chunkTag = El::BuildString("_",realChunk,"_",imagChunk);

                const El::Int imagChunkSize =
                  ( imagChunk==numImag-1 ? yLeftover : yBlock );
                const double imagChunkWidth = imagStep*imagChunkSize;

                const El::Complex<double> chunkCorner = corner +
                    El::Complex<double>
                    (realStep*realChunk*xBlock,imagStep*imagChunk*yBlock);
                const El::Complex<double> chunkCenter = chunkCorner +
                    El::Complex<double>
                    (realStep*realChunkSize,imagStep*imagChunkSize)/2.;

                if( El::mpi::Rank(comm) == 0 )
                    El::Output
                    ("Starting computation for chunk centered at ",chunkCenter);
                El::mpi::Barrier( comm );
                timer.Start();
                psCtrl.snapCtrl.numBase = matName+"_"+numBase+chunkTag;
                psCtrl.snapCtrl.imgBase = matName+"_"+imgBase+chunkTag;
                if( isReal )
                {
                    itCountMap =
                      El::QuasiTriangularSpectralWindow
                      ( AReal, QReal, invNormMap, chunkCenter,
                        realChunkWidth, imagChunkWidth,
                        realChunkSize, imagChunkSize, psCtrl );
                }
                else
                {
                    itCountMap =
                      El::TriangularSpectralWindow
                      ( ACpx, QCpx, invNormMap, chunkCenter,
                        realChunkWidth, imagChunkWidth,
                        realChunkSize, imagChunkSize, psCtrl );
                }
                El::mpi::Barrier( comm );
                const double pseudoTime = timer.Stop();
                const El::Int numIts = MaxNorm( itCountMap );
                if( El::mpi::Rank() == 0 )
                    El::Output
                    ("num seconds=",pseudoTime,"\n",
                     "num iterations=",numIts);
            }
        }
    }
    catch( std::exception& e ) { El::ReportException(e); }

    return 0;
}
示例#18
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> MaxCondition( const Matrix<F>& A )
{
    DEBUG_ONLY(CSE cse("MaxCondition"))
    typedef Base<F> Real;
    Matrix<F> B( A );
    const Real maxNorm = MaxNorm( B );
    try { Inverse( B ); }
    catch( SingularMatrixException& e ) 
    { return std::numeric_limits<Real>::infinity(); }
    const Real maxNormInv = MaxNorm( B );
    return maxNorm*maxNormInv;
}

template<typename F> 
Base<F> MaxCondition( const ElementalMatrix<F>& A )
{
    DEBUG_ONLY(CSE cse("MaxCondition"))
    typedef Base<F> Real;
    DistMatrix<F> B( A );
    const Real maxNorm = MaxNorm( B );
    try { Inverse( B ); }
示例#19
0
inline void ADMM
( const AbstractDistMatrix<F>& MPre, AbstractDistMatrix<F>& LPre, 
        AbstractDistMatrix<F>& SPre, const RPCACtrl<Base<F>>& ctrl )
{
    auto MPtr = ReadProxy<F,MC,MR>( &MPre ); auto& M = *MPtr;
    auto LPtr = WriteProxy<F,MC,MR>( &LPre ); auto& L = *LPtr;
    auto SPtr = WriteProxy<F,MC,MR>( &SPre ); auto& S = *SPtr;

    typedef Base<F> Real;
    const Int m = M.Height();
    const Int n = M.Width();
    const Int commRank = mpi::Rank( M.Grid().Comm() );

    // If tau is not specified, then set it to 1/sqrt(max(m,n))
    const Base<F> tau = 
        ( ctrl.tau <= Real(0) ? Real(1)/sqrt(Real(Max(m,n))) : ctrl.tau );
    if( ctrl.beta <= Real(0) )
        LogicError("beta cannot be non-positive");
    if( ctrl.tol <= Real(0) )
        LogicError("tol cannot be non-positive");
    const Base<F> beta = ctrl.beta;
    const Base<F> tol = ctrl.tol;

    const double startTime = mpi::Time();
    DistMatrix<F> E( M.Grid() ), Y( M.Grid() );
    Zeros( Y, m, n );

    const Real frobM = FrobeniusNorm( M );
    const Real maxM = MaxNorm( M );
    if( ctrl.progress && commRank == 0 )
        cout << "|| M ||_F = " << frobM << "\n"
             << "|| M ||_max = " << maxM << endl;

    Zeros( L, m, n );
    Zeros( S, m, n );

    Int numIts = 0;
    while( true )
    {
        ++numIts;

        // ST_{tau/beta}(M - L + Y/beta)
        S = M;
        Axpy( F(-1), L, S );
        Axpy( F(1)/beta, Y, S );
        SoftThreshold( S, tau/beta );
        const Int numNonzeros = ZeroNorm( S );

        // SVT_{1/beta}(M - S + Y/beta)
        L = M;
        Axpy( F(-1), S, L );
        Axpy( F(1)/beta, Y, L );
        Int rank;
        if( ctrl.usePivQR )
            rank = SVT( L, Real(1)/beta, ctrl.numPivSteps );
        else
            rank = SVT( L, Real(1)/beta );
      
        // E := M - (L + S)
        E = M;    
        Axpy( F(-1), L, E );
        Axpy( F(-1), S, E );
        const Real frobE = FrobeniusNorm( E );

        if( frobE/frobM <= tol )            
        {
            if( ctrl.progress && commRank == 0 )
                cout << "Converged after " << numIts << " iterations "
                     << " with rank=" << rank 
                     << ", numNonzeros=" << numNonzeros << " and "
                     << "|| E ||_F / || M ||_F = " << frobE/frobM
                     << ", and " << mpi::Time()-startTime << " total secs"
                     << endl;
            break;
        }
        else if( numIts >= ctrl.maxIts )
        {
            if( ctrl.progress && commRank == 0 )
                cout << "Aborting after " << numIts << " iterations and "
                     << mpi::Time()-startTime << " total secs" 
                     << endl;
            break;
        }
        else
        {
            if( ctrl.progress && commRank == 0 )
                cout << numIts << ": || E ||_F / || M ||_F = " 
                     << frobE/frobM << ", rank=" << rank 
                     << ", numNonzeros=" << numNonzeros 
                     << ", " << mpi::Time()-startTime << " total secs"
                     << endl;
        }
        
        // Y := Y + beta E
        Axpy( beta, E, Y );
    }
}
示例#20
0
inline void ALM
( const ElementalMatrix<F>& MPre, 
        ElementalMatrix<F>& LPre,
        ElementalMatrix<F>& SPre, 
  const RPCACtrl<Base<F>>& ctrl )
{
    DistMatrixReadProxy<F,F,MC,MR>
      MProx( MPre );
    DistMatrixWriteProxy<F,F,MC,MR>
      LProx( LPre ),
      SProx( SPre );
    auto& M = MProx.GetLocked();
    auto& L = LProx.Get();
    auto& S = SProx.Get();

    typedef Base<F> Real;
    const Int m = M.Height();
    const Int n = M.Width();
    const int commRank = mpi::Rank( M.Grid().Comm() );

    // If tau is unspecified, set it to 1/sqrt(max(m,n))
    const Base<F> tau = 
      ( ctrl.tau <= Real(0) ? Real(1) / sqrt(Real(Max(m,n))) : ctrl.tau );
    if( ctrl.tol <= Real(0) )
        LogicError("tol cannot be non-positive");
    const Base<F> tol = ctrl.tol;

    const double startTime = mpi::Time();

    DistMatrix<F> Y( M );
    NormalizeEntries( Y );
    const Real twoNorm = TwoNorm( Y );
    const Real maxNorm = MaxNorm( Y );
    const Real infNorm = maxNorm / tau; 
    const Real dualNorm = Max( twoNorm, infNorm );
    Y *= F(1)/dualNorm;

    // If beta is unspecified, set it to 1 / 2 || sign(M) ||_2
    Base<F> beta = 
      ( ctrl.beta <= Real(0) ? Real(1) / (2*twoNorm) : ctrl.beta );

    const Real frobM = FrobeniusNorm( M );
    const Real maxM = MaxNorm( M );
    if( ctrl.progress && commRank == 0 )
        cout << "|| M ||_F = " << frobM << "\n"
             << "|| M ||_max = " << maxM << endl;

    Zeros( L, m, n );
    Zeros( S, m, n );

    Int numIts=0, numPrimalIts=0;
    DistMatrix<F> LLast( M.Grid() ), SLast( M.Grid() ), E( M.Grid() );
    while( true )
    {
        ++numIts;
       
        Int rank, numNonzeros;
        while( true )
        {
            ++numPrimalIts;

            LLast = L;
            SLast = S;

            // ST_{tau/beta}(M - L + Y/beta)
            S = M;
            S -= L;
            Axpy( F(1)/beta, Y, S );
            SoftThreshold( S, tau/beta );
            numNonzeros = ZeroNorm( S );

            // SVT_{1/beta}(M - S + Y/beta)
            L = M;
            L -= S;
            Axpy( F(1)/beta, Y, L );
            if( ctrl.usePivQR )
                rank = SVT( L, Real(1)/beta, ctrl.numPivSteps );
            else
                rank = SVT( L, Real(1)/beta );

            LLast -= L;
            SLast -= S;
            const Real frobLDiff = FrobeniusNorm( LLast );
            const Real frobSDiff = FrobeniusNorm( SLast );

            if( frobLDiff/frobM < tol && frobSDiff/frobM < tol )
            {
                if( ctrl.progress && commRank == 0 )
                    cout << "Primal loop converged: " 
                         << mpi::Time()-startTime << " total secs" << endl;
                break;
            }
            else 
            {
                if( ctrl.progress && commRank == 0 )
                    cout << "  " << numPrimalIts 
                         << ": \n"
                         << "   || Delta L ||_F / || M ||_F = " 
                         << frobLDiff/frobM << "\n"
                         << "   || Delta S ||_F / || M ||_F = "
                         << frobSDiff/frobM << "\n"
                         << "   rank=" << rank
                         << ", numNonzeros=" << numNonzeros 
                         << ", " << mpi::Time()-startTime << " total secs" 
                         << endl;
            } 
        }

        // E := M - (L + S)
        E = M;    
        E -= L;
        E -= S;
        const Real frobE = FrobeniusNorm( E );

        if( frobE/frobM <= tol )            
        {
            if( ctrl.progress && commRank == 0 )
                cout << "Converged after " << numIts << " iterations and "
                     << numPrimalIts << " primal iterations with rank=" 
                     << rank << ", numNonzeros=" << numNonzeros << " and "
                     << "|| E ||_F / || M ||_F = " << frobE/frobM
                     << ", " << mpi::Time()-startTime << " total secs"
                     << endl;
            break;
        }
        else if( numIts >= ctrl.maxIts )
        {
            if( ctrl.progress && commRank == 0 )
                cout << "Aborting after " << numIts << " iterations and "
                     << mpi::Time()-startTime << " total secs" << endl;
            break;
        }
        else
        {
            if( ctrl.progress && commRank == 0 )
                cout << numPrimalIts << ": || E ||_F / || M ||_F = " 
                     << frobE/frobM << ", rank=" << rank 
                     << ", numNonzeros=" << numNonzeros << ", "
                     << mpi::Time()-startTime << " total secs" 
                     << endl;
        }
        
        // Y := Y + beta E
        Axpy( beta, E, Y );
        beta *= ctrl.rho;
    }
}
示例#21
0
inline void ADMM
( const Matrix<F>& M, 
        Matrix<F>& L,
        Matrix<F>& S, 
  const RPCACtrl<Base<F>>& ctrl )
{
    typedef Base<F> Real;
    const Int m = M.Height();
    const Int n = M.Width();

    // If tau is not specified, then set it to 1/sqrt(max(m,n))
    const Base<F> tau = 
        ( ctrl.tau <= Real(0) ? Real(1)/sqrt(Real(Max(m,n))) : ctrl.tau );
    if( ctrl.beta <= Real(0) )
        LogicError("beta cannot be non-positive");
    if( ctrl.tol <= Real(0) )
        LogicError("tol cannot be non-positive");
    const Base<F> beta = ctrl.beta;
    const Base<F> tol = ctrl.tol;

    const double startTime = mpi::Time();
    Matrix<F> E, Y;
    Zeros( Y, m, n );

    const Real frobM = FrobeniusNorm( M );
    const Real maxM = MaxNorm( M );
    if( ctrl.progress )
        cout << "|| M ||_F = " << frobM << "\n"
             << "|| M ||_max = " << maxM << endl;

    Zeros( L, m, n );
    Zeros( S, m, n );

    Int numIts = 0;
    while( true )
    {
        ++numIts;

        // ST_{tau/beta}(M - L + Y/beta)
        S = M;
        S -= L;
        Axpy( F(1)/beta, Y, S );
        SoftThreshold( S, tau/beta );
        const Int numNonzeros = ZeroNorm( S );

        // SVT_{1/beta}(M - S + Y/beta)
        L = M;
        L -= S;
        Axpy( F(1)/beta, Y, L );
        Int rank;
        if( ctrl.usePivQR )
            rank = SVT( L, Real(1)/beta, ctrl.numPivSteps );
        else
            rank = SVT( L, Real(1)/beta );
      
        // E := M - (L + S)
        E = M;    
        E -= L;
        E -= S;
        const Real frobE = FrobeniusNorm( E );

        if( frobE/frobM <= tol )            
        {
            if( ctrl.progress )
                cout << "Converged after " << numIts << " iterations "
                     << " with rank=" << rank 
                     << ", numNonzeros=" << numNonzeros << " and "
                     << "|| E ||_F / || M ||_F = " << frobE/frobM
                     << ", and " << mpi::Time()-startTime << " total secs"
                     << endl;
            break;
        }
        else if( numIts >= ctrl.maxIts )
        {
            if( ctrl.progress )
                cout << "Aborting after " << numIts << " iterations and "
                     << mpi::Time()-startTime << " total secs" 
                     << endl;
            break;
        }
        else
        {
            if( ctrl.progress )
                cout << numIts << ": || E ||_F / || M ||_F = " 
                     << frobE/frobM << ", rank=" << rank 
                     << ", numNonzeros=" << numNonzeros 
                     << ", " << mpi::Time()-startTime << " total secs"
                     << endl;
        }
        
        // Y := Y + beta E
        Axpy( beta, E, Y );
    }
}