Base<Field> FrobeniusNorm( const SparseMatrix<Field>& A ) { EL_DEBUG_CSE typedef Base<Field> Real; Real scale = 0; Real scaledSquare = 1; const Int numEntries = A.NumEntries(); const Field* valBuf = A.LockedValueBuffer(); for( Int k=0; k<numEntries; ++k ) UpdateScaledSquare( valBuf[k], scale, scaledSquare ); return scale*Sqrt(scaledSquare); }
Base<Field> FrobeniusNorm( const Matrix<Field>& A ) { EL_DEBUG_CSE typedef Base<Field> Real; Real scale = 0; Real scaledSquare = 1; const Int width = A.Width(); const Int height = A.Height(); for( Int j=0; j<width; ++j ) for( Int i=0; i<height; ++i ) UpdateScaledSquare( A(i,j), scale, scaledSquare ); return scale*Sqrt(scaledSquare); }
Matrix<Base<Field>> NestedColumnTwoNorms( const Matrix<Field>& Z, Int numNested=1 ) { EL_DEBUG_CSE typedef Base<Field> Real; const Int n = Z.Height(); const Int numRHS = Z.Width(); Matrix<Real> colNorms(numRHS,numNested); // Compute nested norms in linear time for( Int j=0; j<numRHS; ++j ) { const Field* zBuf = Z.LockedBuffer(0,j); Real scale=0, scaledSquare=1; for( Int i=n-1; i>=numNested; --i ) UpdateScaledSquare( zBuf[i], scale, scaledSquare ); for( Int i=numNested-1; i>=0; --i ) { UpdateScaledSquare( zBuf[i], scale, scaledSquare ); colNorms(j,i) = scale*Sqrt(scaledSquare); } } return colNorms; }
void RowTwoNorms( const SparseMatrix<F>& A, Matrix<Base<F>>& norms ) { DEBUG_CSE typedef Base<F> Real; const Int m = A.Height(); const F* valBuf = A.LockedValueBuffer(); const Int* offsetBuf = A.LockedOffsetBuffer(); norms.Resize( m, 1 ); for( Int i=0; i<m; ++i ) { Real scale = 0; Real scaledSquare = 1; const Int offset = offsetBuf[i]; const Int numConn = offsetBuf[i+1] - offset; for( Int e=offset; e<offset+numConn; ++e ) UpdateScaledSquare( valBuf[e], scale, scaledSquare ); norms(i) = scale*Sqrt(scaledSquare); } }
void RowTwoNorms( const DistSparseMatrix<F>& A, DistMultiVec<Base<F>>& norms ) { DEBUG_CSE typedef Base<F> Real; const Int localHeight = A.LocalHeight(); const F* valBuf = A.LockedValueBuffer(); const Int* offsetBuf = A.LockedOffsetBuffer(); norms.SetComm( A.Comm() ); norms.Resize( A.Height(), 1 ); auto& normLoc = norms.Matrix(); for( Int iLoc=0; iLoc<localHeight; ++iLoc ) { Real scale = 0; Real scaledSquare = 1; const Int offset = offsetBuf[iLoc]; const Int numConn = offsetBuf[iLoc+1] - offset; for( Int e=offset; e<offset+numConn; ++e ) UpdateScaledSquare( valBuf[e], scale, scaledSquare ); normLoc(iLoc) = scale*Sqrt(scaledSquare); } }
void RowTwoNormsHelper ( const Matrix<F>& ALoc, Matrix<Base<F>>& normsLoc, mpi::Comm comm ) { DEBUG_CSE typedef Base<F> Real; const Int mLocal = ALoc.Height(); const Int nLocal = ALoc.Width(); // TODO: Ensure that NaN's propagate Matrix<Real> localScales(mLocal,1 ), localScaledSquares(mLocal,1); for( Int iLoc=0; iLoc<mLocal; ++iLoc ) { Real localScale = 0; Real localScaledSquare = 1; for( Int jLoc=0; jLoc<nLocal; ++jLoc ) UpdateScaledSquare ( ALoc(iLoc,jLoc), localScale, localScaledSquare ); localScales(iLoc) = localScale; localScaledSquares(iLoc) = localScaledSquare; } NormsFromScaledSquares( localScales, localScaledSquares, normsLoc, comm ); }