void StackedRuizEquil ( DistSparseMatrix<Field>& A, DistSparseMatrix<Field>& B, DistMultiVec<Base<Field>>& dRowA, DistMultiVec<Base<Field>>& dRowB, DistMultiVec<Base<Field>>& dCol, bool progress ) { EL_DEBUG_CSE typedef Base<Field> Real; const Int mA = A.Height(); const Int mB = B.Height(); const Int n = A.Width(); mpi::Comm comm = A.Comm(); dRowA.SetComm( comm ); dRowB.SetComm( comm ); dCol.SetComm( comm ); Ones( dRowA, mA, 1 ); Ones( dRowB, mB, 1 ); Ones( dCol, n, 1 ); // TODO(poulson): Expose to control structure // For, simply hard-code a small number of iterations const Int maxIter = 4; DistMultiVec<Real> scales(comm), maxAbsValsB(comm); auto& scalesLoc = scales.Matrix(); auto& maxAbsValsBLoc = maxAbsValsB.Matrix(); const Int localHeight = scalesLoc.Height(); const Int indent = PushIndent(); for( Int iter=0; iter<maxIter; ++iter ) { // Rescale the columns // ------------------- ColumnMaxNorms( A, scales ); ColumnMaxNorms( B, maxAbsValsB ); for( Int jLoc=0; jLoc<localHeight; ++jLoc ) scalesLoc(jLoc) = Max(scalesLoc(jLoc),maxAbsValsBLoc(jLoc)); EntrywiseMap( scales, MakeFunction(DampScaling<Real>) ); DiagonalScale( LEFT, NORMAL, scales, dCol ); DiagonalSolve( RIGHT, NORMAL, scales, A ); DiagonalSolve( RIGHT, NORMAL, scales, B ); // Rescale the rows // ---------------- RowMaxNorms( A, scales ); EntrywiseMap( scales, MakeFunction(DampScaling<Real>) ); DiagonalScale( LEFT, NORMAL, scales, dRowA ); DiagonalSolve( LEFT, NORMAL, scales, A ); RowMaxNorms( B, scales ); EntrywiseMap( scales, MakeFunction(DampScaling<Real>) ); DiagonalScale( LEFT, NORMAL, scales, dRowB ); DiagonalSolve( LEFT, NORMAL, scales, B ); } SetIndent( indent ); }
void StackedGeometricColumnScaling ( const DistMatrix<Field, U,V >& A, const DistMatrix<Field, U,V >& B, DistMatrix<Base<Field>,V,STAR>& geomScaling ) { EL_DEBUG_CSE // NOTE: Assuming A.ColComm() == B.ColComm() and that the row alignments // are equal typedef Base<Field> Real; DistMatrix<Real,V,STAR> maxScalingA(A.Grid()), maxScalingB(A.Grid()); ColumnMaxNorms( A, maxScalingA ); ColumnMaxNorms( B, maxScalingB ); const Int mLocalA = A.LocalHeight(); const Int mLocalB = B.LocalHeight(); const Int nLocal = A.LocalWidth(); geomScaling.AlignWith( maxScalingA ); geomScaling.Resize( A.Width(), 1 ); auto& ALoc = A.LockedMatrix(); auto& BLoc = B.LockedMatrix(); auto& geomScalingLoc = geomScaling.Matrix(); auto& maxScalingALoc = maxScalingA.Matrix(); auto& maxScalingBLoc = maxScalingB.Matrix(); for( Int jLoc=0; jLoc<nLocal; ++jLoc ) { Real minAbs = Max(maxScalingALoc(jLoc),maxScalingBLoc(jLoc)); for( Int iLoc=0; iLoc<mLocalA; ++iLoc ) { const Real absVal = Abs(ALoc(iLoc,jLoc)); if( absVal > 0 && absVal < minAbs ) minAbs = Min(minAbs,absVal); } for( Int iLoc=0; iLoc<mLocalB; ++iLoc ) { const Real absVal = Abs(BLoc(iLoc,jLoc)); if( absVal > 0 && absVal < minAbs ) minAbs = Min(minAbs,absVal); } geomScalingLoc(jLoc) = minAbs; } mpi::AllReduce( geomScaling.Buffer(), nLocal, mpi::MIN, A.ColComm() ); for( Int jLoc=0; jLoc<nLocal; ++jLoc ) { const Real maxAbsA = maxScalingALoc(jLoc); const Real maxAbsB = maxScalingBLoc(jLoc); const Real maxAbs = Max(maxAbsA,maxAbsB); const Real minAbs = geomScalingLoc(jLoc); geomScalingLoc(jLoc) = Sqrt(minAbs*maxAbs); } }
void StackedRuizEquil ( SparseMatrix<Field>& A, SparseMatrix<Field>& B, Matrix<Base<Field>>& dRowA, Matrix<Base<Field>>& dRowB, Matrix<Base<Field>>& dCol, bool progress ) { EL_DEBUG_CSE typedef Base<Field> Real; const Int mA = A.Height(); const Int mB = B.Height(); const Int n = A.Width(); Ones( dRowA, mA, 1 ); Ones( dRowB, mB, 1 ); Ones( dCol, n, 1 ); // TODO(poulson): Expose these as control parameters // For now, simply hard-code the number of iterations const Int maxIter = 4; Matrix<Real> scales, maxAbsValsB; const Int indent = PushIndent(); for( Int iter=0; iter<maxIter; ++iter ) { // Rescale the columns // ------------------- ColumnMaxNorms( A, scales ); ColumnMaxNorms( B, maxAbsValsB ); for( Int j=0; j<n; ++j ) scales(j) = Max(scales(j),maxAbsValsB(j)); EntrywiseMap( scales, MakeFunction(DampScaling<Real>) ); DiagonalScale( LEFT, NORMAL, scales, dCol ); DiagonalSolve( RIGHT, NORMAL, scales, A ); DiagonalSolve( RIGHT, NORMAL, scales, B ); // Rescale the rows // ---------------- RowMaxNorms( A, scales ); EntrywiseMap( scales, MakeFunction(DampScaling<Real>) ); DiagonalScale( LEFT, NORMAL, scales, dRowA ); DiagonalSolve( LEFT, NORMAL, scales, A ); RowMaxNorms( B, scales ); EntrywiseMap( scales, MakeFunction(DampScaling<Real>) ); DiagonalScale( LEFT, NORMAL, scales, dRowB ); DiagonalSolve( LEFT, NORMAL, scales, B ); } SetIndent( indent ); }
void SymmetricRuizEquil ( DistSparseMatrix<F>& A, DistMultiVec<Base<F>>& d, Int maxIter, bool progress ) { DEBUG_CSE typedef Base<F> Real; const Int n = A.Height(); mpi::Comm comm = A.Comm(); d.SetComm( comm ); Ones( d, n, 1 ); DistMultiVec<Real> scales(comm); const Int indent = PushIndent(); for( Int iter=0; iter<maxIter; ++iter ) { // Rescale the columns (and rows) // ------------------------------ ColumnMaxNorms( A, scales ); EntrywiseMap( scales, function<Real(Real)>(DampScaling<Real>) ); EntrywiseMap( scales, function<Real(Real)>(SquareRootScaling<Real>) ); DiagonalScale( LEFT, NORMAL, scales, d ); SymmetricDiagonalSolve( scales, A ); } SetIndent( indent ); }
void SymmetricRuizEquil ( Matrix<F>& A, Matrix<Base<F>>& d, Int maxIter, bool progress ) { DEBUG_CSE typedef Base<F> Real; const Int n = A.Height(); Ones( d, n, 1 ); Matrix<Real> scales; const Int indent = PushIndent(); for( Int iter=0; iter<maxIter; ++iter ) { // Rescale the columns (and rows) // ------------------------------ ColumnMaxNorms( A, scales ); EntrywiseMap( scales, function<Real(Real)>(DampScaling<Real>) ); EntrywiseMap( scales, function<Real(Real)>(SquareRootScaling<Real>) ); DiagonalScale( LEFT, NORMAL, scales, d ); // TODO(poulson): Replace with SymmetricDiagonalSolve DiagonalSolve( RIGHT, NORMAL, scales, A ); DiagonalSolve( LEFT, NORMAL, scales, A ); } SetIndent( indent ); }
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 StackedGeometricColumnScaling ( const Matrix<Field>& A, const Matrix<Field>& B, Matrix<Base<Field>>& geomScaling ) { EL_DEBUG_CSE typedef Base<Field> Real; Matrix<Real> maxScalingA, maxScalingB; ColumnMaxNorms( A, maxScalingA ); ColumnMaxNorms( B, maxScalingB ); const Int mA = A.Height(); const Int mB = B.Height(); const Int n = A.Width(); geomScaling.Resize( n, 1 ); for( Int j=0; j<n; ++j ) { Real minAbs = Max(maxScalingA(j),maxScalingB(j)); for( Int i=0; i<mA; ++i ) { const Real absVal = Abs(A(i,j)); if( absVal > 0 && absVal < minAbs ) minAbs = Min(minAbs,absVal); } for( Int i=0; i<mB; ++i ) { const Real absVal = Abs(B(i,j)); if( absVal > 0 && absVal < minAbs ) minAbs = Min(minAbs,absVal); } geomScaling(j) = minAbs; } for( Int j=0; j<n; ++j ) { const Real maxAbsA = maxScalingA(j); const Real maxAbsB = maxScalingB(j); const Real maxAbs = Max(maxAbsA,maxAbsB); const Real minAbs = geomScaling(j); geomScaling(j) = Sqrt(minAbs*maxAbs); } }
void RuizEquil ( AbstractDistMatrix<Field>& APre, AbstractDistMatrix<Base<Field>>& dRowPre, AbstractDistMatrix<Base<Field>>& dColPre, bool progress ) { EL_DEBUG_CSE typedef Base<Field> Real; ElementalProxyCtrl control; control.colConstrain = true; control.rowConstrain = true; control.colAlign = 0; control.rowAlign = 0; DistMatrixReadWriteProxy<Field,Field,MC,MR> AProx( APre, control ); DistMatrixWriteProxy<Real,Real,MC,STAR> dRowProx( dRowPre, control ); DistMatrixWriteProxy<Real,Real,MR,STAR> dColProx( dColPre, control ); auto& A = AProx.Get(); auto& dRow = dRowProx.Get(); auto& dCol = dColProx.Get(); const Int m = A.Height(); const Int n = A.Width(); Ones( dRow, m, 1 ); Ones( dCol, n, 1 ); // TODO(poulson): Expose these as control parameters // For now, simply hard-code the number of iterations const Int maxIter = 4; DistMatrix<Real,MC,STAR> rowScale(A.Grid()); DistMatrix<Real,MR,STAR> colScale(A.Grid()); const Int indent = PushIndent(); for( Int iter=0; iter<maxIter; ++iter ) { // Rescale the columns // ------------------- ColumnMaxNorms( A, colScale ); EntrywiseMap( colScale, MakeFunction(DampScaling<Real>) ); DiagonalScale( LEFT, NORMAL, colScale, dCol ); DiagonalSolve( RIGHT, NORMAL, colScale, A ); // Rescale the rows // ---------------- RowMaxNorms( A, rowScale ); EntrywiseMap( rowScale, MakeFunction(DampScaling<Real>) ); DiagonalScale( LEFT, NORMAL, rowScale, dRow ); DiagonalSolve( LEFT, NORMAL, rowScale, A ); } SetIndent( indent ); }
void GeometricColumnScaling ( const DistMatrix<Field, U,V >& A, DistMatrix<Base<Field>,V,STAR>& geomScaling ) { EL_DEBUG_CSE typedef Base<Field> Real; DistMatrix<Real,V,STAR> maxScaling(A.Grid()); ColumnMaxNorms( A, maxScaling ); ColumnMinAbsNonzero( A, maxScaling, geomScaling ); const Int nLocal = A.LocalWidth(); auto& maxScalingLoc = maxScaling.Matrix(); auto& geomScalingLoc = geomScaling.Matrix(); for( Int jLoc=0; jLoc<nLocal; ++jLoc ) { const Real maxAbs = maxScalingLoc(jLoc); const Real minAbs = geomScalingLoc(jLoc); geomScalingLoc(jLoc) = Sqrt(minAbs*maxAbs); } }
void RuizEquil ( DistSparseMatrix<Field>& A, DistMultiVec<Base<Field>>& dRow, DistMultiVec<Base<Field>>& dCol, bool progress ) { EL_DEBUG_CSE typedef Base<Field> Real; const Int m = A.Height(); const Int n = A.Width(); mpi::Comm comm = A.Comm(); dRow.SetComm( comm ); dCol.SetComm( comm ); Ones( dRow, m, 1 ); Ones( dCol, n, 1 ); // TODO(poulson): Expose to control structure // For, simply hard-code a small number of iterations const Int maxIter = 4; DistMultiVec<Real> scales(comm); const Int indent = PushIndent(); for( Int iter=0; iter<maxIter; ++iter ) { // Rescale the columns // ------------------- ColumnMaxNorms( A, scales ); EntrywiseMap( scales, MakeFunction(DampScaling<Real>) ); DiagonalScale( LEFT, NORMAL, scales, dCol ); DiagonalSolve( RIGHT, NORMAL, scales, A ); // Rescale the rows // ---------------- RowMaxNorms( A, scales ); EntrywiseMap( scales, MakeFunction(DampScaling<Real>) ); DiagonalScale( LEFT, NORMAL, scales, dRow ); DiagonalSolve( LEFT, NORMAL, scales, A ); } SetIndent( indent ); }
void SymmetricRuizEquil ( ElementalMatrix<F>& APre, ElementalMatrix<Base<F>>& dPre, Int maxIter, bool progress ) { DEBUG_CSE typedef Base<F> Real; ElementalProxyCtrl control; control.colConstrain = true; control.rowConstrain = true; control.colAlign = 0; control.rowAlign = 0; DistMatrixReadWriteProxy<F,F,MC,MR> AProx( APre, control ); DistMatrixWriteProxy<Real,Real,MC,STAR> dProx( dPre, control ); auto& A = AProx.Get(); auto& d = dProx.Get(); const Int n = A.Height(); Ones( d, n, 1 ); DistMatrix<Real,MR,STAR> scales(A.Grid()); const Int indent = PushIndent(); for( Int iter=0; iter<maxIter; ++iter ) { // Rescale the columns (and rows) // ------------------------------ ColumnMaxNorms( A, scales ); EntrywiseMap( scales, function<Real(Real)>(DampScaling<Real>) ); EntrywiseMap( scales, function<Real(Real)>(SquareRootScaling<Real>) ); DiagonalScale( LEFT, NORMAL, scales, d ); // TODO: Replace with SymmetricDiagonalSolve DiagonalSolve( RIGHT, NORMAL, scales, A ); DiagonalSolve( LEFT, NORMAL, scales, A ); } SetIndent( indent ); }
void RuizEquil ( Matrix<Field>& A, Matrix<Base<Field>>& dRow, Matrix<Base<Field>>& dCol, bool progress ) { EL_DEBUG_CSE typedef Base<Field> Real; const Int m = A.Height(); const Int n = A.Width(); Ones( dRow, m, 1 ); Ones( dCol, n, 1 ); // TODO(poulson): Expose these as control parameters // For now, simply hard-code the number of iterations const Int maxIter = 4; Matrix<Real> rowScale, colScale; const Int indent = PushIndent(); for( Int iter=0; iter<maxIter; ++iter ) { // Rescale the columns // ------------------- ColumnMaxNorms( A, colScale ); EntrywiseMap( colScale, MakeFunction(DampScaling<Real>) ); DiagonalScale( LEFT, NORMAL, colScale, dCol ); DiagonalSolve( RIGHT, NORMAL, colScale, A ); // Rescale the rows // ---------------- RowMaxNorms( A, rowScale ); EntrywiseMap( rowScale, MakeFunction(DampScaling<Real>) ); DiagonalScale( LEFT, NORMAL, rowScale, dRow ); DiagonalSolve( LEFT, NORMAL, rowScale, A ); } SetIndent( indent ); }