HessenbergSchurInfo
HessenbergSchur
( AbstractDistMatrix<F>& HPre,
  AbstractDistMatrix<Complex<Base<F>>>& wPre,
  AbstractDistMatrix<F>& ZPre,
  const HessenbergSchurCtrl& ctrl )
{
    EL_DEBUG_CSE
    typedef Base<F> Real;

    DistMatrixReadWriteProxy<F,F,MC,MR,BLOCK> HProx( HPre );
    auto& H = HProx.Get();

    DistMatrixWriteProxy<Complex<Real>,Complex<Real>,STAR,STAR> wProx( wPre );
    auto& w = wProx.Get();

    ProxyCtrl proxCtrl;
    proxCtrl.colConstrain = true;
    proxCtrl.rowConstrain = true;
    proxCtrl.colAlign = H.ColAlign();
    proxCtrl.rowAlign = H.RowAlign();
    proxCtrl.colCut = H.ColCut();
    proxCtrl.rowCut = H.RowCut();
    // Technically, the 'Read' portion of the proxy is only needed if
    // ctrl.accumulateSchurVecs is true.
    DistMatrixReadWriteProxy<F,F,MC,MR,BLOCK> ZProx( ZPre, proxCtrl );
    auto& Z = ZProx.Get();

    const Int n = H.Height();
    auto ctrlMod( ctrl );
    ctrlMod.winBeg = ( ctrl.winBeg==END ? n : ctrl.winBeg );
    ctrlMod.winEnd = ( ctrl.winEnd==END ? n : ctrl.winEnd );
    ctrlMod.wantSchurVecs = true;
    if( !ctrl.accumulateSchurVecs )
    {
        Identity( Z, n, n );
        ctrlMod.accumulateSchurVecs = true;
    }

    if( ctrlMod.scalapack )
    {
#ifdef EL_HAVE_SCALAPACK
        if( IsBlasScalar<F>::value )
            return hess_schur::ScaLAPACKHelper( H, w, Z, ctrlMod );
        else
            Output("Warning: ScaLAPACK is not supported for this datatype");
#else
        Output("Warning: Elemental was not configured with ScaLAPACK support");
#endif
    }

    if( ctrl.alg == HESSENBERG_SCHUR_AED )
    {
        return hess_schur::AED( H, w, Z, ctrlMod );
    }
    else
    {
        return hess_schur::MultiBulge( H, w, Z, ctrlMod );
    }
}
void NesterovTodd
( const ElementalMatrix<Real>& sPre, 
  const ElementalMatrix<Real>& zPre,
        ElementalMatrix<Real>& wPre )
{
    DEBUG_CSE

    ElementalProxyCtrl ctrl;
    ctrl.colConstrain = true;
    ctrl.colAlign = 0;

    DistMatrixReadProxy<Real,Real,VC,STAR>
      sProx( sPre, ctrl ),
      zProx( zPre, ctrl );
    DistMatrixWriteProxy<Real,Real,VC,STAR>
      wProx( wPre, ctrl );
    auto& s = sProx.GetLocked();
    auto& z = zProx.GetLocked();
    auto& w = wProx.Get();

    w.Resize( s.Height(), 1 );
    const Int localHeight = w.LocalHeight();
    const Real* sBuf = s.LockedBuffer();
    const Real* zBuf = z.LockedBuffer();
          Real* wBuf = w.Buffer();

    for( Int iLoc=0; iLoc<localHeight; ++iLoc )
        wBuf[iLoc] = Sqrt(sBuf[iLoc]/zBuf[iLoc]);
}
HessenbergSchurInfo
ScaLAPACKHelper
( AbstractDistMatrix<F>& HPre,
  AbstractDistMatrix<Complex<Base<F>>>& wPre,
  AbstractDistMatrix<F>& ZPre,
  const HessenbergSchurCtrl& ctrl )
{
    EL_DEBUG_CSE
    typedef Base<F> Real;
    AssertScaLAPACKSupport();
    HessenbergSchurInfo info;

    ProxyCtrl proxyCtrl;
    proxyCtrl.colConstrain = true;
    proxyCtrl.rowConstrain = true;
    proxyCtrl.blockHeight = ctrl.blockHeight;
    proxyCtrl.blockWidth = ctrl.blockHeight;
    proxyCtrl.colAlign = 0;
    proxyCtrl.rowAlign = 0;
    proxyCtrl.colCut = 0;
    proxyCtrl.rowCut = 0;

    DistMatrixReadWriteProxy<F,F,MC,MR,BLOCK> HProx( HPre, proxyCtrl );
    auto& H = HProx.Get();
    const Int n = H.Height();

    DistMatrixReadWriteProxy<F,F,MC,MR,BLOCK> ZProx( ZPre, proxyCtrl );
    auto& Z = ZProx.Get();
    if( !ctrl.accumulateSchurVecs )
        Identity( Z, n, n );

    DistMatrixWriteProxy<Complex<Real>,Complex<Real>,STAR,STAR> wProx( wPre );
    auto& w = wProx.Get();

#ifdef EL_HAVE_SCALAPACK
    bool accumulateSchurVecs=true;
    bool useAED = ( ctrl.alg == HESSENBERG_SCHUR_AED );

    auto descH = FillDesc( H );
    scalapack::HessenbergSchur
    ( n,
      H.Buffer(), descH.data(),
      w.Buffer(),
      Z.Buffer(), descH.data(),
      ctrl.fullTriangle,
      accumulateSchurVecs,
      useAED );
    // TODO(poulson): Find a way to fill in info?
#endif

    return info;
}
void HermitianFromEVD
( UpperOrLower uplo, 
        AbstractDistMatrix<F>& APre,
  const AbstractDistMatrix<Base<F>>& wPre,
  const AbstractDistMatrix<F>& ZPre )
{
    DEBUG_CSE
    typedef Base<F> Real;

    DistMatrixWriteProxy<F,F,MC,MR> AProx( APre );
    DistMatrixReadProxy<Real,Real,VR,STAR> wProx( wPre );
    DistMatrixReadProxy<F,F,MC,MR> ZProx( ZPre );
    auto& A = AProx.Get();
    auto& w = wProx.GetLocked();
    auto& Z = ZProx.GetLocked();

    const Grid& g = A.Grid();
    DistMatrix<F,MC,  STAR> Z1_MC_STAR(g);
    DistMatrix<F,VR,  STAR> Z1_VR_STAR(g);
    DistMatrix<F,STAR,MR  > Z1Adj_STAR_MR(g);

    const Int m = Z.Height();
    const Int n = Z.Width();
    A.Resize( m, m );
    if( uplo == LOWER )
        MakeTrapezoidal( UPPER, A, 1 );
    else
        MakeTrapezoidal( LOWER, A, -1 );
    const Int bsize = Blocksize();
    for( Int k=0; k<n; k+=bsize )
    {
        const Int nb = Min(bsize,n-k);
        auto Z1 = Z( ALL,        IR(k,k+nb) );
        auto w1 = w( IR(k,k+nb), ALL        );

        Z1_MC_STAR.AlignWith( A );
        Z1_MC_STAR = Z1;
        Z1_VR_STAR.AlignWith( A );
        Z1_VR_STAR = Z1_MC_STAR;

        DiagonalScale( RIGHT, NORMAL, w1, Z1_VR_STAR );

        Z1Adj_STAR_MR.AlignWith( A );
        Adjoint( Z1_VR_STAR, Z1Adj_STAR_MR );
        LocalTrrk( uplo, F(1), Z1_MC_STAR, Z1Adj_STAR_MR, F(1), A );
    }
}
Exemple #5
0
void PushPairInto
(       ElementalMatrix<Real>& sPre, 
        ElementalMatrix<Real>& zPre,
  const ElementalMatrix<Real>& wPre,
  const ElementalMatrix<Int>& ordersPre, 
  const ElementalMatrix<Int>& firstIndsPre,
  Real wMaxNormLimit, Int cutoff )
{
    DEBUG_ONLY(CSE cse("soc::PushPairInto"))
    AssertSameGrids( sPre, zPre, wPre, ordersPre, firstIndsPre );

    ElementalProxyCtrl ctrl;
    ctrl.colConstrain = true;
    ctrl.colAlign = 0;

    DistMatrixReadWriteProxy<Real,Real,VC,STAR>
      sProx( sPre, ctrl ),
      zProx( zPre, ctrl );
    DistMatrixReadProxy<Real,Real,VC,STAR>
      wProx( wPre, ctrl );
    DistMatrixReadProxy<Int,Int,VC,STAR>
      ordersProx( ordersPre, ctrl ),
      firstIndsProx( firstIndsPre, ctrl );
    auto& s = sProx.Get();
    auto& z = zProx.Get();
    auto& w = wProx.GetLocked();
    auto& orders = ordersProx.GetLocked();
    auto& firstInds = firstIndsProx.GetLocked();

    DistMatrix<Real,VC,STAR> sLower(s.Grid()), zLower(z.Grid());
    soc::LowerNorms( s, sLower, orders, firstInds, cutoff );
    soc::LowerNorms( z, zLower, orders, firstInds, cutoff );

    const Int localHeight = s.LocalHeight();
    for( Int iLoc=0; iLoc<localHeight; ++iLoc )
    {
        const Int i = s.GlobalRow(iLoc);
        const Real w0 = w.GetLocal(iLoc,0);
        if( i == firstInds.GetLocal(iLoc,0) && w0 > wMaxNormLimit )
        {
            // TODO: Switch to a non-adhoc modification     
            s.UpdateLocal( iLoc, 0, Real(1)/wMaxNormLimit );
            z.UpdateLocal( iLoc, 0, Real(1)/wMaxNormLimit );
        }
    }
}
HessenbergSchurInfo
HessenbergSchur
( AbstractDistMatrix<F>& HPre,
  AbstractDistMatrix<Complex<Base<F>>>& wPre,
  const HessenbergSchurCtrl& ctrl )
{
    EL_DEBUG_CSE
    typedef Base<F> Real;

    DistMatrixReadWriteProxy<F,F,MC,MR,BLOCK> HProx( HPre );
    auto& H = HProx.Get();

    DistMatrixWriteProxy<Complex<Real>,Complex<Real>,STAR,STAR> wProx( wPre );
    auto& w = wProx.Get();

    DistMatrix<F,MC,MR,BLOCK> Z(H.Grid());
    Z.AlignWith( H );

    const Int n = H.Height();
    auto ctrlMod( ctrl );
    ctrlMod.winBeg = ( ctrl.winBeg==END ? n : ctrl.winBeg );
    ctrlMod.winEnd = ( ctrl.winEnd==END ? n : ctrl.winEnd );
    ctrlMod.wantSchurVecs = false;

    if( ctrlMod.scalapack )
    {
#ifdef EL_HAVE_SCALAPACK
        if( IsBlasScalar<F>::value )
            return hess_schur::ScaLAPACKHelper( H, w, ctrlMod );
        else
            Output("Warning: ScaLAPACK is not supported for this datatype");
#else
        Output("Warning: Elemental was not configured with ScaLAPACK support");
#endif
    }

    if( ctrl.alg == HESSENBERG_SCHUR_AED )
    {
        return hess_schur::AED( H, w, Z, ctrlMod );
    }
    else
    {
        return hess_schur::MultiBulge( H, w, Z, ctrlMod );
    }
}
void SortAndFilter
( AbstractDistMatrix<Real>& wPre, const HermitianTridiagEigCtrl<Real>& ctrl )
{
    DEBUG_CSE

    DistMatrixReadWriteProxy<Real,Real,STAR,STAR> wProx( wPre );
    auto& w = wProx.Get();

    const Int n = w.Height();
    const Grid& g = w.Grid();

    if( ctrl.subset.indexSubset )
    {
        Sort( w, ctrl.sort );
        DistMatrix<Real,STAR,STAR> wCopy( w );
        w = wCopy(IR(ctrl.subset.lowerIndex,ctrl.subset.upperIndex+1),ALL);
    }
    else if( ctrl.subset.rangeSubset )
    {
        Int numValid = 0;

        for( Int j=0; j<n; ++j )
            if( w.GetLocal(j,0) > ctrl.subset.lowerBound &&
                w.GetLocal(j,0) <= ctrl.subset.upperBound )
                ++numValid;

        DistMatrix<Real,STAR,STAR> wFilter(numValid,1,g);
        numValid = 0;
        for( Int j=0; j<n; ++j )
           if( w.GetLocal(j,0) > ctrl.subset.lowerBound &&
               w.GetLocal(j,0) <= ctrl.subset.upperBound )
               wFilter.SetLocal( numValid++, 0, w.GetLocal(j,0) );

        w = wFilter;
        Sort( w, ctrl.sort );
    }
    else
    {
        Sort( w, ctrl.sort );
    }
}
void SortAndFilter
( AbstractDistMatrix<Base<F>>& wPre,
  AbstractDistMatrix<F>& QPre,
  const HermitianTridiagEigCtrl<Base<F>>& ctrl )
{
    DEBUG_CSE
    typedef Base<F> Real;

    DistMatrixReadWriteProxy<Real,Real,STAR,STAR> wProx( wPre );
    DistMatrixReadWriteProxy<F,F,VC,STAR> QProx( QPre );
    auto& w = wProx.Get();
    auto& Q = QProx.Get();

    const Int n = w.Height();
    const Grid& g = w.Grid();

    if( ctrl.subset.indexSubset )
    {
        auto sortPairs = TaggedSort( w, ctrl.sort );
        for( Int j=0; j<n; ++j )
            w.SetLocal( j, 0, sortPairs[j].value );
        ApplyTaggedSortToEachRow( sortPairs, Q );

        DistMatrix<Real,STAR,STAR> wCopy( w );
        DistMatrix<F,VC,STAR> QCopy( Q );
        w = wCopy(IR(ctrl.subset.lowerIndex,ctrl.subset.upperIndex+1),ALL);
        Q = QCopy(ALL,IR(ctrl.subset.lowerIndex,ctrl.subset.upperIndex+1));
    }
    else if( ctrl.subset.rangeSubset )
    {
        Int numValid = 0;

        for( Int j=0; j<n; ++j )
            if( w.GetLocal(j,0) > ctrl.subset.lowerBound &&
                w.GetLocal(j,0) <= ctrl.subset.upperBound )
                ++numValid;

        DistMatrix<Real,STAR,STAR> wFilter(numValid,1,g);
        DistMatrix<F,VC,STAR> QFilter(n,numValid,g);
        numValid = 0;
        for( Int j=0; j<n; ++j )
        {
           if( w.GetLocal(j,0) > ctrl.subset.lowerBound &&
               w.GetLocal(j,0) <= ctrl.subset.upperBound )
           {
               wFilter.SetLocal( numValid, 0, w.GetLocal(j,0) );
               auto qFilterCol = QFilter(ALL,IR(numValid));
               qFilterCol = Q(ALL,IR(j));
               ++numValid;
           }
        }

        w = wFilter;
        Q = QFilter;

        auto sortPairs = TaggedSort( w, ctrl.sort );
        for( Int j=0; j<numValid; ++j )
            w.SetLocal( j, 0, sortPairs[j].value );
        ApplyTaggedSortToEachRow( sortPairs, Q );
    }
    else
    {
        auto sortPairs = TaggedSort( w, ctrl.sort );
        for( Int j=0; j<n; ++j )
            w.SetLocal( j, 0, sortPairs[j].value );
        ApplyTaggedSortToEachRow( sortPairs, Q );
    }
}