void SymmetricRuizEquil ( DistSparseMatrix<Field>& A, DistMultiVec<Base<Field>>& d, Int maxIter, bool progress ) { EL_DEBUG_CSE typedef Base<Field> Real; const Int n = A.Height(); const Grid& grid = A.Grid(); d.SetGrid( grid ); Ones( d, n, 1 ); DistMultiVec<Real> scales(grid); const Int indent = PushIndent(); for( Int iter=0; iter<maxIter; ++iter ) { // Rescale the columns (and rows) // ------------------------------ ColumnMaxNorms( A, scales ); EntrywiseMap( scales, MakeFunction(DampScaling<Real>) ); EntrywiseMap( scales, MakeFunction(SquareRootScaling<Real>) ); DiagonalScale( LEFT, NORMAL, scales, d ); SymmetricDiagonalSolve( scales, A ); } SetIndent( indent ); }
void GetMappedDiagonal ( const DistSparseMatrix<T>& A, DistMultiVec<S>& d, function<S(const T&)> func, Int offset ) { EL_DEBUG_CSE const Int m = A.Height(); const Int n = A.Width(); const T* valBuf = A.LockedValueBuffer(); const Int* colBuf = A.LockedTargetBuffer(); if( m != n ) LogicError("DistSparseMatrix GetMappedDiagonal assumes square matrix"); if( offset != 0 ) LogicError("DistSparseMatrix GetMappedDiagonal assumes offset=0"); d.SetGrid( A.Grid() ); d.Resize( El::DiagonalLength(m,n,offset), 1 ); Fill( d, S(1) ); S* dBuf = d.Matrix().Buffer(); const Int dLocalHeight = d.LocalHeight(); for( Int iLoc=0; iLoc<dLocalHeight; ++iLoc ) { const Int i = d.GlobalRow(iLoc); const Int thisOff = A.RowOffset(iLoc); const Int nextOff = A.RowOffset(iLoc+1); auto it = std::lower_bound( colBuf+thisOff, colBuf+nextOff, i ); if( *it == i ) { const Int e = it-colBuf; dBuf[iLoc] = func(valBuf[e]); } else dBuf[iLoc] = func(0); } }