void ConsistentlyComputeDecomposition ( DistMatrix<Field,MC,MR,BLOCK>& H, DistMatrix<Complex<Base<Field>>,STAR,STAR>& w, Matrix<Field>& Z, const HessenbergSchurCtrl& ctrl=HessenbergSchurCtrl() ) { EL_DEBUG_CSE // Because double-precision floating-point computation is often // non-deterministic due to extra-precision computation being frequent but // not guaranteed, we must be careful to not allow this non-determinism to // be amplified by the forward instability of Francis sweeps. const Grid& grid = H.Grid(); const int owner = H.Owner(0,0); DistMatrix<Field,CIRC,CIRC> H_CIRC_CIRC( grid, owner ); H_CIRC_CIRC = H; w.Resize( H.Height(), 1 ); if( H_CIRC_CIRC.CrossRank() == H_CIRC_CIRC.Root() ) HessenbergSchur( H_CIRC_CIRC.Matrix(), w.Matrix(), Z, ctrl ); else Z.Resize( H.Height(), H.Height() ); H = H_CIRC_CIRC; El::Broadcast( w.Matrix(), H_CIRC_CIRC.CrossComm(), H_CIRC_CIRC.Root() ); El::Broadcast( Z, H_CIRC_CIRC.CrossComm(), H_CIRC_CIRC.Root() ); }
AEDInfo NibbleHelper ( Matrix<Real>& H, Real& spikeValue, Matrix<Complex<Real>>& w, Matrix<Real>& V, const HessenbergSchurCtrl& ctrl ) { EL_DEBUG_CSE const Int n = H.Height(); AEDInfo info; const Real zero(0); const Real ulp = limits::Precision<Real>(); const Real safeMin = limits::SafeMin<Real>(); const Real smallNum = safeMin*(Real(n)/ulp); Zeros( V, 0, 0 ); if( n == 1 ) { w(0) = H(0,0); if( Abs(spikeValue) <= Max( smallNum, ulp*Abs(w(0).real()) ) ) { // The offdiagonal entry was small enough to deflate info.numDeflated = 1; spikeValue = zero; } else { // The offdiagonal entry was too large to deflate info.numShiftCandidates = 1; } return info; } // NOTE(poulson): We could only copy the upper-Hessenberg portion of H auto T( H ); // TODO(poulson): Reuse this matrix? Identity( V, n, n ); auto ctrlSub( ctrl ); ctrlSub.winBeg = 0; ctrlSub.winEnd = n; ctrlSub.fullTriangle = true; ctrlSub.wantSchurVecs = true; ctrlSub.demandConverged = false; ctrlSub.alg = ( ctrl.recursiveAED ? HESSENBERG_SCHUR_AED : HESSENBERG_SCHUR_MULTIBULGE ); auto infoSub = HessenbergSchur( T, w, V, ctrlSub ); EL_DEBUG_ONLY( if( infoSub.numUnconverged != 0 ) Output(infoSub.numUnconverged," eigenvalues did not converge"); )
AEDInfo Nibble ( Matrix<Real>& H, Int deflationSize, Matrix<Complex<Real>>& w, Matrix<Real>& Z, const HessenbergSchurCtrl& ctrl ) { DEBUG_CSE const Int n = H.Height(); Int winBeg = ( ctrl.winBeg==END ? n : ctrl.winBeg ); Int winEnd = ( ctrl.winEnd==END ? n : ctrl.winEnd ); AEDInfo info; const Real zero(0); const Real ulp = limits::Precision<Real>(); const Real safeMin = limits::SafeMin<Real>(); const Real smallNum = safeMin*(Real(n)/ulp); if( winBeg > winEnd ) return info; if( deflationSize < 1 ) return info; Int blockSize = Min( deflationSize, winEnd-winBeg ); const Int deflateBeg = winEnd-blockSize; // If the deflation window touches the beginning of the full window, // then there is no spike Real spikeValue = ( deflateBeg==winBeg ? zero : H(deflateBeg,deflateBeg-1) ); if( blockSize == 1 ) { w(deflateBeg) = H(deflateBeg,deflateBeg); if( Abs(spikeValue) <= Max( smallNum, ulp*Abs(w(deflateBeg).real()) ) ) { // The offdiagonal entry was small enough to deflate info.numDeflated = 1; if( deflateBeg > winBeg ) { // Explicitly deflate by zeroing the offdiagonal entry H(deflateBeg,deflateBeg-1) = zero; } } else { // The offdiagonal entry was too large to deflate info.numShiftCandidates = 1; } return info; } auto deflateInd = IR(deflateBeg,winEnd); auto H11 = H( deflateInd, deflateInd ); // NOTE(poulson): We could only copy the upper-Hessenberg portion of H11 auto T( H11 ); // TODO(poulson): Reuse this matrix? auto w1 = w( deflateInd, ALL ); Matrix<Real> V; Identity( V, blockSize, blockSize ); auto ctrlSub( ctrl ); ctrlSub.winBeg = 0; ctrlSub.winEnd = blockSize; ctrlSub.fullTriangle = true; ctrlSub.wantSchurVecs = true; ctrlSub.demandConverged = false; ctrlSub.alg = ( ctrl.recursiveAED ? HESSENBERG_SCHUR_AED : HESSENBERG_SCHUR_MULTIBULGE ); auto infoSub = HessenbergSchur( T, w1, V, ctrlSub ); DEBUG_ONLY( if( infoSub.numUnconverged != 0 ) Output(infoSub.numUnconverged," eigenvalues did not converge"); )