Example #1
0
void PhaseEnumerationLeafInner
(       PhaseEnumerationCache<Field>& cache,
  const PhaseEnumerationCtrl& ctrl,
        vector<pair<Int,Field>>& y,
  const Int beg,
  const Int baseInf,
  const Int baseOne )
{
    EL_DEBUG_CSE
    const Int n = ctrl.phaseOffsets.back();
    const Int minInf = ctrl.minInfNorms.back();
    const Int maxInf = ctrl.maxInfNorms.back();
    const Int minOne = ctrl.minOneNorms.back();
    const Int maxOne = ctrl.maxOneNorms.back();
    const bool constrained = (y.size() == 0);

    SpiralState<Field> spiral;
    spiral.Initialize( constrained );
    while( true )
    {
        const Field beta = spiral.Step();
        const Int betaInf = Int(MaxAbs(beta));
        const Int betaOne = Int(OneAbs(beta));
        const Int newInf = Max(betaInf,baseInf);
        const Int newOne = betaOne + baseOne;
        if( newInf > maxInf || newOne > maxOne )
            break;

        if( newOne >= minOne && newInf >= minInf )
        {
            for( Int i=beg; i<n; ++i )
            {
                if( ctrl.enqueueProb >= 1. ||
                    SampleUniform<double>(0,1) <= ctrl.enqueueProb )
                {
                    y.emplace_back( i, beta );
                    cache.Enqueue( y );
                    y.pop_back();
                }
            }
        }

        if( newOne < maxOne )
        {
            // We can insert beta into any position and still have room
            // left for the one norm bound, so do so and then recurse
            for( Int i=beg; i<n-1; ++i )
            {
                y.emplace_back( i, beta );
                PhaseEnumerationLeafInner
                ( cache, ctrl, y, i+1, newInf, newOne );
                y.pop_back();
            }
        }
    }
}
Example #2
0
Int DetectSmallSubdiagonal( const Matrix<F>& H )
{
    DEBUG_CSE
    typedef Base<F> Real;

    const Int n = H.Height();
    const Real ulp = limits::Precision<Real>();
    const Real safeMin = limits::SafeMin<Real>();
    const Real smallNum = safeMin*(Real(n)/ulp);

    // Search up the subdiagonal
    for( Int k=n-2; k>=0; --k )
    {
        const F eta00 = H(k,k);
        const F eta01 = H(k,k+1);
        const Real eta10 = RealPart( H(k+1,k) );
        const F eta11 = H(k+1,k+1);
        if( OneAbs(eta10) <= smallNum )
        {
            return k+1;
        }

        Real localScale = OneAbs(eta00) + OneAbs(eta11);
        if( localScale == Real(0) )
        {
            // Search outward a bit to get a sense of the matrix's local scale
            if( k-1 >= 0 )
                localScale += Abs( RealPart( H(k,k-1) ) );
            if( k+2 <= n-1 )
                localScale += Abs( RealPart( H(k+2,k+1) ) );
        }
        
        if( Abs(eta10) <= ulp*localScale )
        {
            const Real maxOff = Max( Abs(eta10), OneAbs(eta01) );
            const Real minOff = Min( Abs(eta10), OneAbs(eta01) ); 

            const Real diagDiff = OneAbs(eta00-eta11);
            const Real maxDiag = Max( OneAbs(eta11), diagDiff );
            const Real minDiag = Min( OneAbs(eta11), diagDiff );

            const Real sigma = maxDiag + maxOff;
            if( minOff*(maxOff/sigma) <=
                Max(smallNum,ulp*(minDiag*(maxDiag/sigma))) )
            {
                return k+1;
            }
        }
    }
    return 0;
}
Example #3
0
      const bool conjugate = ( shift0.imag() == -shift1.imag() );
      if( !bothReal && !conjugate )
          LogicError("Assumed shifts were either both real or conjugates");
    )
    if( n == 2 )
    {
        const Real& eta00 = H(0,0);
        const Real& eta01 = H(0,1);
        const Real& eta10 = H(1,0);
        const Real& eta11 = H(1,1);

        // It seems arbitrary whether the scale is computed relative
        // to shift0 or shift1, but we follow LAPACK's convention.
        // (While the choice is irrelevant for conjugate shifts, it is not for
        //  real shifts)
        const Real scale = OneAbs(eta00-shift1) + Abs(eta10);
        if( scale == zero )
        {
            v[0] = v[1] = zero;
        }
        else
        {
            // Normalize the first column by the scale
            Real eta10Scale = eta10 / scale;
            v[0] = eta10Scale*eta01 +
                   (eta00-shift0.real())*((eta00-shift1.real())/scale) -
                   shift0.imag()*(shift1.imag()/scale);
            v[1] = eta10Scale*(eta00+eta11-shift0.real()-shift1.real());
        }
    }
    else