Ejemplo n.º 1
0
inline void
Hanowa( DistMatrix<T,U,V>& A, int n, T mu )
{
#ifndef RELEASE
    CallStackEntry entry("Hanowa");
#endif
    if( n % 2 != 0 )
        throw std::logic_error("n must be an even integer");
    A.ResizeTo( n, n );
    const int m = n/2;
    std::vector<T> d(m);
    DistMatrix<T,U,V> ABlock( A.Grid() );

    for( int j=0; j<m; ++j )
        d[j] = mu;
    View( ABlock, A, 0, 0, m, m );
    Diagonal( ABlock, d );
    View( ABlock, A, m, m, m, m );
    Diagonal( ABlock, d );

    for( int j=0; j<m; ++j )
        d[j] = -(j+1);
    View( ABlock, A, 0, m, m, m );
    Diagonal( ABlock, d );

    for( int j=0; j<m; ++j )
        d[j] = j+1;
    View( ABlock, A, m, 0, m, m );
    Diagonal( ABlock, d );
}
Ejemplo n.º 2
0
void MakeExtendedKahan
( ElementalMatrix<F>& A, Base<F> phi, Base<F> mu )
{
    EL_DEBUG_CSE
    typedef Base<F> Real;

    if( A.Height() != A.Width() )
        LogicError("Extended Kahan matrices must be square");
    const Int n = A.Height();
    if( n % 3 != 0 )
        LogicError("Dimension must be an integer multiple of 3");
    const Int l = n / 3;
    if( !l || (l & (l-1)) )
        LogicError("n/3 is not a power of two");
    Int k=0;
    while( Int(1u<<k) < l )
        ++k;

    if( phi <= Real(0) || phi >= Real(1) )
        LogicError("phi must be in (0,1)");
    if( mu <= Real(0) || mu >= Real(1) )
        LogicError("mu must be in (0,1)");

    // Start by setting A to the identity, and then modify the necessary 
    // l x l blocks of its 3 x 3 partitioning.
    MakeIdentity( A );
    unique_ptr<ElementalMatrix<F>> ABlock( A.Construct(A.Grid(),A.Root()) );
    View( *ABlock, A, IR(2*l,3*l), IR(2*l,3*l) );
    *ABlock *= mu;
    View( *ABlock, A, IR(0,l), IR(l,2*l) );
    Walsh( *ABlock, k );
    *ABlock *= -phi;
    View( *ABlock, A, IR(l,2*l), IR(2*l,3*l) );
    Walsh( *ABlock, k );
    *ABlock *= phi;

    // Now scale A by S
    const Real zeta = Sqrt(Real(1)-phi*phi);
    auto& ALoc = A.Matrix();
    for( Int iLoc=0; iLoc<A.LocalHeight(); ++iLoc )
    {
        const Int i = A.GlobalRow(iLoc);
        const Real gamma = Pow(zeta,Real(i));
        for( Int jLoc=0; jLoc<A.LocalWidth(); ++jLoc )
            ALoc(iLoc,jLoc) *= gamma;
    }
}