inline void MakeDiscreteFourier( DistMatrix<Complex<R>,U,V>& A ) { #ifndef RELEASE CallStackEntry entry("MakeDiscreteFourier"); #endif typedef Complex<R> F; const int m = A.Height(); const int n = A.Width(); if( m != n ) throw std::logic_error("Cannot make a non-square DFT matrix"); const R pi = 4*Atan( R(1) ); const F nSqrt = Sqrt( R(n) ); const int localHeight = A.LocalHeight(); const int localWidth = A.LocalWidth(); const int colShift = A.ColShift(); const int rowShift = A.RowShift(); const int colStride = A.ColStride(); const int rowStride = A.RowStride(); for( int jLocal=0; jLocal<localWidth; ++jLocal ) { const int j = rowShift + jLocal*rowStride; for( int iLocal=0; iLocal<localHeight; ++iLocal ) { const int i = colShift + iLocal*colStride; A.SetLocal( iLocal, jLocal, Exp(-2*pi*i*j/n)/nSqrt ); const R theta = -2*pi*i*j/n; const Complex<R> alpha( Cos(theta), Sin(theta) ); A.SetLocal( iLocal, jLocal, alpha/nSqrt ); } } }
inline void BinaryFlat ( DistMatrix<T,U,V>& A, Int height, Int width, const std::string filename ) { DEBUG_ONLY(CallStackEntry cse("read::Binary")) std::ifstream file( filename.c_str(), std::ios::binary ); if( !file.is_open() ) RuntimeError("Could not open ",filename); const Int numBytes = FileSize( file ); const Int numBytesExp = height*width*sizeof(T); if( numBytes != numBytesExp ) RuntimeError ("Expected file to be ",numBytesExp," bytes but found ",numBytes); A.Resize( height, width ); const Int localHeight = A.LocalHeight(); const Int localWidth = A.LocalWidth(); const Int colShift = A.ColShift(); const Int rowShift = A.RowShift(); const Int colStride = A.ColStride(); const Int rowStride = A.RowStride(); for( Int jLoc=0; jLoc<localWidth; ++jLoc ) { const Int j = rowShift + jLoc*rowStride; for( Int iLoc=0; iLoc<localHeight; ++iLoc ) { const Int i = colShift + iLoc*colStride; const Int localIndex = i+j*height; const std::streamoff pos = localIndex*sizeof(T); file.seekg( pos ); file.read( (char*)A.Buffer(iLoc,jLoc), sizeof(T) ); } } }
inline void Riemann( DistMatrix<T,U,V>& R, int n ) { #ifndef RELEASE CallStackEntry entry("Riemann"); #endif R.ResizeTo( n, n ); const int localHeight = R.LocalHeight(); const int localWidth = R.LocalWidth(); const int colShift = R.ColShift(); const int rowShift = R.RowShift(); const int colStride = R.ColStride(); const int rowStride = R.RowStride(); for( int jLocal=0; jLocal<localWidth; ++jLocal ) { const int j = rowShift + jLocal*rowStride; for( int iLocal=0; iLocal<localHeight; ++iLocal ) { const int i = colShift + iLocal*colStride; if( ((j+2)%(i+2))==0 ) R.SetLocal( iLocal, jLocal, T(i+1) ); else R.SetLocal( iLocal, jLocal, T(-1) ); } } }
inline void Hankel( DistMatrix<T,U,V>& A, Int m, Int n, const std::vector<T>& a ) { #ifndef RELEASE CallStackEntry entry("Hankel"); #endif const Int length = m+n-1; if( a.size() != (Unsigned)length ) LogicError("a was the wrong size"); A.ResizeTo( m, n ); const Int localHeight = A.LocalHeight(); const Int localWidth = A.LocalWidth(); const Int colShift = A.ColShift(); const Int rowShift = A.RowShift(); const Int colStride = A.ColStride(); const Int rowStride = A.RowStride(); for( Int jLoc=0; jLoc<localWidth; ++jLoc ) { const Int j = rowShift + jLoc*rowStride; for( Int iLoc=0; iLoc<localHeight; ++iLoc ) { const Int i = colShift + iLoc*colStride; A.SetLocal( iLoc, jLoc, a[i+j] ); } } }
inline void Diagonal( const std::vector<T>& d, DistMatrix<T,U,V>& D ) { #ifndef RELEASE PushCallStack("Diagonal"); #endif const int n = d.size(); D.ResizeTo( n, n ); MakeZeros( D ); const int localWidth = D.LocalWidth(); const int colShift = D.ColShift(); const int rowShift = D.RowShift(); const int colStride = D.ColStride(); const int rowStride = D.RowStride(); for( int jLocal=0; jLocal<localWidth; ++jLocal ) { const int j = rowShift + jLocal*rowStride; if( (j-colShift+colStride) % colStride == 0 ) { const int iLocal = (j-colShift) / colStride; D.SetLocal( iLocal, jLocal, d[j] ); } } #ifndef RELEASE PopCallStack(); #endif }
inline void Redheffer( DistMatrix<T,U,V>& R, Int n ) { #ifndef RELEASE CallStackEntry entry("Redheffer"); #endif R.ResizeTo( n, n ); const Int localHeight = R.LocalHeight(); const Int localWidth = R.LocalWidth(); const Int colShift = R.ColShift(); const Int rowShift = R.RowShift(); const Int colStride = R.ColStride(); const Int rowStride = R.RowStride(); for( Int jLoc=0; jLoc<localWidth; ++jLoc ) { const Int j = rowShift + jLoc*rowStride; for( Int iLoc=0; iLoc<localHeight; ++iLoc ) { const Int i = colShift + iLoc*colStride; if( j==0 || ((j+1)%(i+1))==0 ) R.SetLocal( iLoc, jLoc, T(1) ); else R.SetLocal( iLoc, jLoc, T(0) ); } } }
const DistMatrix<T,MD,STAR>& DistMatrix<T,MD,STAR>::operator=( const DistMatrix<T,MD,STAR>& A ) { #ifndef RELEASE CallStackEntry entry("[MD,* ] = [MD,* ]"); this->AssertNotLocked(); this->AssertSameGrid( A.Grid() ); #endif if( !this->Viewing() && !this->ConstrainedColAlignment() ) { this->diagPath_ = A.diagPath_; this->colAlignment_ = A.colAlignment_; if( this->Participating() ) this->colShift_ = A.ColShift(); } this->ResizeTo( A.Height(), A.Width() ); if( this->diagPath_ == A.diagPath_ && this->colAlignment_ == A.colAlignment_ ) { this->matrix_ = A.LockedMatrix(); } else { #ifdef UNALIGNED_WARNINGS if( this->Grid().Rank() == 0 ) std::cerr << "Unaligned [MD,* ] <- [MD,* ]." << std::endl; #endif LogicError("Unaligned [MD,* ] = [MD,* ] not yet implemented"); } return *this; }
inline void MakeOneTwoOne( DistMatrix<T,U,V>& A ) { #ifndef RELEASE PushCallStack("MakeOneTwoOne"); #endif if( A.Height() != A.Width() ) throw std::logic_error("Cannot make a non-square matrix 1-2-1"); MakeZeros( A ); const int localHeight = A.LocalHeight(); const int localWidth = A.LocalWidth(); const int colShift = A.ColShift(); const int rowShift = A.RowShift(); const int colStride = A.ColStride(); const int rowStride = A.RowStride(); for( int jLocal=0; jLocal<localWidth; ++jLocal ) { const int j = rowShift + jLocal*rowStride; for( int iLocal=0; iLocal<localHeight; ++iLocal ) { const int i = colShift + iLocal*colStride; if( i == j ) A.SetLocal( iLocal, jLocal, T(2) ); else if( i == j-1 || i == j+1 ) A.SetLocal( iLocal, jLocal, T(1) ); } } #ifndef RELEASE PopCallStack(); #endif }
inline typename Base<F>::type HermitianEntrywiseOneNorm( UpperOrLower uplo, const DistMatrix<F>& A ) { #ifndef RELEASE PushCallStack("HermitianEntrywiseOneNorm"); #endif if( A.Height() != A.Width() ) throw std::logic_error("Hermitian matrices must be square."); const int r = A.Grid().Height(); const int c = A.Grid().Width(); const int colShift = A.ColShift(); const int rowShift = A.RowShift(); typedef typename Base<F>::type R; R localSum = 0; const int localWidth = A.LocalWidth(); if( uplo == UPPER ) { for( int jLocal=0; jLocal<localWidth; ++jLocal ) { int j = rowShift + jLocal*c; int numUpperRows = Length(j+1,colShift,r); for( int iLocal=0; iLocal<numUpperRows; ++iLocal ) { int i = colShift + iLocal*r; const R alpha = Abs(A.GetLocal(iLocal,jLocal)); if( i ==j ) localSum += alpha; else localSum += 2*alpha; } } } else { for( int jLocal=0; jLocal<localWidth; ++jLocal ) { int j = rowShift + jLocal*c; int numStrictlyUpperRows = Length(j,colShift,r); for( int iLocal=numStrictlyUpperRows; iLocal<A.LocalHeight(); ++iLocal ) { int i = colShift + iLocal*r; const R alpha = Abs(A.GetLocal(iLocal,jLocal)); if( i ==j ) localSum += alpha; else localSum += 2*alpha; } } } R norm; mpi::AllReduce( &localSum, &norm, 1, mpi::SUM, A.Grid().VCComm() ); #ifndef RELEASE PopCallStack(); #endif return norm; }
//phi = (rand(m,n)-.5)*pi; void phi_uniform(DistMatrix<R> &U){ boost::random::uniform_01<> dist; boost::random::mt19937 rng(static_cast<boost::uint32_t>(commRank)); R temp; R pi = 4*atan(1); const int colShift = U.ColShift(); // first row we own const int rowShift = U.RowShift(); // first col we own const int colStride = U.ColStride(); const int rowStride = U.RowStride(); const int localHeight = U.LocalHeight(); const int localWidth = U.LocalWidth(); for( int iLocal=0; iLocal<localHeight; ++iLocal ){ for( int jLocal=0; jLocal<localWidth; ++jLocal ){ const int i = colShift + iLocal*colStride; const int j = rowShift + jLocal*rowStride; temp = dist(rng); U.SetLocal(iLocal, jLocal, ((temp-0.5)*pi) ); } } }
inline void Wilkinson( DistMatrix<T,U,V>& A, int k ) { #ifndef RELEASE CallStackEntry entry("Wilkinson"); #endif const int n = 2*k+1; A.ResizeTo( n, n ); MakeZeros( A ); const int localHeight = A.LocalHeight(); const int localWidth = A.LocalWidth(); const int colShift = A.ColShift(); const int rowShift = A.RowShift(); const int colStride = A.ColStride(); const int rowStride = A.RowStride(); for( int jLocal=0; jLocal<localWidth; ++jLocal ) { const int j = rowShift + jLocal*rowStride; for( int iLocal=0; iLocal<localHeight; ++iLocal ) { const int i = colShift + iLocal*colStride; if( i == j ) { if( j <= k ) A.SetLocal( iLocal, jLocal, T(k-j) ); else A.SetLocal( iLocal, jLocal, T(j-k) ); } else if( i == j-1 || i == j+1 ) A.SetLocal( iLocal, jLocal, T(1) ); } } }
void calc_x_else(const R alpha, const R beta,const R c, const R delta, DistMatrix<R> &x, DistMatrix<R> &phi,DistMatrix<R> &w){ R bphi; R temp; R temp2; const R pi = 4*atan(1); const int colShift = x.ColShift(); // first row we own const int rowShift = x.RowShift(); // first col we own const int colStride = x.ColStride(); const int rowStride = x.RowStride(); const int localHeight = x.LocalHeight(); const int localWidth = x.LocalWidth(); for( int iLocal=0; iLocal<localHeight; ++iLocal ){ for( int jLocal=0; jLocal<localWidth; ++jLocal ){ const int i = colShift + iLocal*colStride; const int j = rowShift + jLocal*rowStride; temp = phi.GetLocal(0,jLocal);//phi temp2 = w.GetLocal(0,jLocal); //w bphi = (pi/2) + beta * temp; //cout<< (delta + c * (((2/pi) * (bphi * tan(temp) - beta * log((pi/2) * temp2 * cos(temp) / bphi))) + (beta * tan (pi *alpha/2))))<<endl; x.SetLocal(iLocal, jLocal, (-1* sqrt(abs(delta + c * (((2/pi) * (bphi * tan(temp) - beta * log((pi/2) * temp2 * cos(temp) / bphi))) + (beta * tan (pi *alpha/2))))))); } } }
inline void Hankel( int m, int n, const std::vector<T>& a, DistMatrix<T,U,V>& A ) { #ifndef RELEASE PushCallStack("Hankel"); #endif const int length = m+n-1; if( a.size() != (unsigned)length ) throw std::logic_error("a was the wrong size"); A.ResizeTo( m, n ); const int localHeight = A.LocalHeight(); const int localWidth = A.LocalWidth(); const int colShift = A.ColShift(); const int rowShift = A.RowShift(); const int colStride = A.ColStride(); const int rowStride = A.RowStride(); for( int jLocal=0; jLocal<localWidth; ++jLocal ) { const int j = rowShift + jLocal*rowStride; for( int iLocal=0; iLocal<localHeight; ++iLocal ) { const int i = colShift + iLocal*colStride; A.SetLocal( iLocal, jLocal, a[i+j] ); } } #ifndef RELEASE PopCallStack(); #endif }
inline void MakeGKS( DistMatrix<F,U,V>& A ) { #ifndef RELEASE CallStackEntry entry("MakeGKS"); #endif const Int m = A.Height(); const Int n = A.Width(); if( m != n ) LogicError("Cannot make a non-square matrix GKS"); const Int localHeight = A.LocalHeight(); const Int localWidth = A.LocalWidth(); const Int colShift = A.ColShift(); const Int rowShift = A.RowShift(); const Int colStride = A.ColStride(); const Int rowStride = A.RowStride(); for( Int jLoc=0; jLoc<localWidth; ++jLoc ) { const Int j = rowShift + jLoc*rowStride; const F jDiag = F(1)/Sqrt(F(j)); for( Int iLoc=0; iLoc<localHeight; ++iLoc ) { const Int i = colShift + iLoc*colStride; if( i < j ) A.SetLocal( iLoc, jLoc, -jDiag ); else if( i == j ) A.SetLocal( iLoc, jLoc, jDiag ); else A.SetLocal( iLoc, jLoc, 0 ); } } }
inline bool PivotParity( const DistMatrix<int,VC,STAR>& p, int pivotOffset ) { #ifndef RELEASE PushCallStack("PivotParity"); if( p.Width() != 1 ) throw std::logic_error("p must be a column vector"); if( pivotOffset < 0 ) throw std::logic_error("pivot offset cannot be negative"); #endif const int mLocal = p.LocalHeight(); const Grid& g = p.Grid(); bool isLocallyOdd = false; const int colShift = p.ColShift(); const int gridSize = g.Size(); for( int iLocal=0; iLocal<mLocal; ++iLocal ) { const int i = colShift + iLocal*gridSize; if( p.GetLocal(iLocal,0) != i+pivotOffset ) isLocallyOdd = !isLocallyOdd; } int localContribution = isLocallyOdd; int globalContribution; mpi::AllReduce ( &localContribution, &globalContribution, 1, MPI_SUM, g.VCComm() ); globalContribution = globalContribution % 2; bool isOdd = globalContribution; #ifndef RELEASE PopCallStack(); #endif return isOdd; }
inline void MakeJordan( DistMatrix<T,U,V>& J, T lambda ) { DEBUG_ONLY(CallStackEntry cse("MakeJordan")) Zero( J.Matrix() ); const Int localHeight = J.LocalHeight(); const Int localWidth = J.LocalWidth(); const Int colShift = J.ColShift(); const Int rowShift = J.RowShift(); const Int colStride = J.ColStride(); const Int rowStride = J.RowStride(); for( Int jLoc=0; jLoc<localWidth; ++jLoc ) { const Int j = rowShift + jLoc*rowStride; for( Int iLoc=0; iLoc<localHeight; ++iLoc ) { const Int i = colShift + iLoc*colStride; if( i == j ) J.SetLocal( iLoc, jLoc, lambda ); else if( i == j-1 ) J.SetLocal( iLoc, jLoc, T(1) ); } } }
inline void Pei( DistMatrix<T,U,V>& P, Int n, T alpha ) { #ifndef RELEASE CallStackEntry entry("MakeIdentity"); #endif P.ResizeTo( n, n ); const Int localHeight = P.LocalHeight(); const Int localWidth = P.LocalWidth(); const Int colShift = P.ColShift(); const Int rowShift = P.RowShift(); const Int colStride = P.ColStride(); const Int rowStride = P.RowStride(); for( Int jLoc=0; jLoc<localWidth; ++jLoc ) { const Int j = rowShift + jLoc*rowStride; for( Int iLoc=0; iLoc<localHeight; ++iLoc ) { const Int i = colShift + iLoc*colStride; P.SetLocal( iLoc, jLoc, T(1) ); if( i == j ) P.UpdateLocal( iLoc, jLoc, alpha ); } } }
inline void MakeLegendre( DistMatrix<F,U,V>& A ) { #ifndef RELEASE CallStackEntry entry("MakeLegendre"); #endif if( A.Height() != A.Width() ) LogicError("Cannot make a non-square matrix Legendre"); MakeZeros( A ); const Int localHeight = A.LocalHeight(); const Int localWidth = A.LocalWidth(); const Int colShift = A.ColShift(); const Int rowShift = A.RowShift(); const Int colStride = A.ColStride(); const Int rowStride = A.RowStride(); for( Int jLoc=0; jLoc<localWidth; ++jLoc ) { const Int j = rowShift + jLoc*rowStride; for( Int iLoc=0; iLoc<localHeight; ++iLoc ) { const Int i = colShift + iLoc*colStride; if( j == i+1 || j == i-1 ) { const Int k = Max( i, j ); const F gamma = F(1) / Pow( F(2)*k, F(2) ); const F beta = F(1) / (2*Sqrt(F(1)-gamma)); A.SetLocal( iLoc, jLoc, beta ); } } } }
void calc_x_if(const R alpha,const R beta,const R c, const R delta,DistMatrix<R> &x, DistMatrix<R> &phi,DistMatrix<R> &w){ R temp; // phi R temp2; // w R aphi; R a1phi; const R pi = 4*atan(1); const R zeta = beta * tan(pi * alpha/2); const int colShift = x.ColShift(); // first row we own const int rowShift = x.RowShift(); // first col we own const int colStride = x.ColStride(); const int rowStride = x.RowStride(); const int localHeight = x.LocalHeight(); const int localWidth = x.LocalWidth(); for( int iLocal=0; iLocal<localHeight; ++iLocal ){ for( int jLocal=0; jLocal<localWidth; ++jLocal ){ const int i = colShift + iLocal*colStride; const int j = rowShift + jLocal*rowStride; temp = phi.GetLocal(iLocal,jLocal);//phi temp2 = w.GetLocal(iLocal,jLocal); //w aphi = alpha * temp; a1phi = (1-alpha)*temp; x.SetLocal(iLocal, jLocal, (-1 * sqrt(abs(delta + c *( ( (sin(aphi)+zeta * cos(aphi))/ cos(temp)) * -1 * pow( abs( ((cos(a1phi) + zeta * sin(a1phi))/ (temp2 * cos(temp))) ) ,((1-alpha)/alpha) ) + beta * tan(pi * alpha/2) )))) ); } } }
inline void MakeHilbert( DistMatrix<F,U,V>& A ) { #ifndef RELEASE PushCallStack("MakeHilbert"); #endif const int m = A.Height(); const int n = A.Width(); if( m != n ) throw std::logic_error("Cannot make a non-square matrix Hilbert"); const F one = static_cast<F>(1); const int localHeight = A.LocalHeight(); const int localWidth = A.LocalWidth(); const int colShift = A.ColShift(); const int rowShift = A.RowShift(); const int colStride = A.ColStride(); const int rowStride = A.RowStride(); for( int jLocal=0; jLocal<localWidth; ++jLocal ) { const int j = rowShift + jLocal*rowStride; for( int iLocal=0; iLocal<localHeight; ++iLocal ) { const int i = colShift + iLocal*colStride; A.SetLocalEntry( iLocal, jLocal, one/(i+j+1) ); } } #ifndef RELEASE PopCallStack(); #endif }
//w = -log(rand(m,n)); void log_uniform(DistMatrix<R> &U){ //boost::random::gamma_distribution<> dist(df/2.0,2.0); boost::random::uniform_01<> dist; boost::random::mt19937 rng(static_cast<boost::uint32_t>(commRank)); double temp; const int colShift = U.ColShift(); // first row we own const int rowShift = U.RowShift(); // first col we own const int colStride = U.ColStride(); const int rowStride = U.RowStride(); const int localHeight = U.LocalHeight(); const int localWidth = U.LocalWidth(); for( int iLocal=0; iLocal<localHeight; ++iLocal ){ for( int jLocal=0; jLocal<localWidth; ++jLocal ){ const int i = colShift + iLocal*colStride; const int j = rowShift + jLocal*rowStride; temp = dist(rng); U.SetLocal(iLocal, jLocal, log(temp)); } } }
void dotproduct(DistMatrix<R> &A,DistMatrix<R> &B){ if(A.Height() != B.Height()){ //ERROR! } if(A.Width() != B.Width()){ //ERROR! } double temp,temp1; const int colShift = A.ColShift(); // first row we own const int rowShift = A.RowShift(); // first col we own const int colStride = A.ColStride(); const int rowStride = A.RowStride(); const int localHeight = A.LocalHeight(); const int localWidth = A.LocalWidth(); for( int iLocal=0; iLocal<localHeight; ++iLocal ){ for( int jLocal=0; jLocal<localWidth; ++jLocal ){ const int i = colShift + iLocal*colStride; const int j = rowShift + jLocal*rowStride; temp = A.GetLocal(iLocal, jLocal); temp1 = B.GetLocal(iLocal,jLocal); B.SetLocal(iLocal, jLocal, (temp*temp1)); } } }
inline void MakeHilbert( DistMatrix<F,U,V>& A ) { #ifndef RELEASE CallStackEntry entry("MakeHilbert"); #endif const Int m = A.Height(); const Int n = A.Width(); if( m != n ) LogicError("Cannot make a non-square matrix Hilbert"); const F one = F(1); const Int localHeight = A.LocalHeight(); const Int localWidth = A.LocalWidth(); const Int colShift = A.ColShift(); const Int rowShift = A.RowShift(); const Int colStride = A.ColStride(); const Int rowStride = A.RowStride(); for( Int jLoc=0; jLoc<localWidth; ++jLoc ) { const Int j = rowShift + jLoc*rowStride; for( Int iLoc=0; iLoc<localHeight; ++iLoc ) { const Int i = colShift + iLoc*colStride; A.SetLocal( iLoc, jLoc, one/(i+j+1) ); } } }
inline void MakeTriangular( UpperOrLower uplo, DistMatrix<T,U,V>& A ) { #ifndef RELEASE PushCallStack("MakeTriangular"); #endif const int height = A.Height(); const int localHeight = A.LocalHeight(); const int localWidth = A.LocalWidth(); const int colShift = A.ColShift(); const int rowShift = A.RowShift(); const int colStride = A.ColStride(); const int rowStride = A.RowStride(); T* localBuffer = A.LocalBuffer(); const int ldim = A.LocalLDim(); if( uplo == LOWER ) { #ifdef HAVE_OPENMP #pragma omp parallel for #endif for( int jLocal=0; jLocal<localWidth; ++jLocal ) { const int j = rowShift + jLocal*rowStride; const int lastZeroRow = j-1; if( lastZeroRow >= 0 ) { const int boundary = std::min( lastZeroRow+1, height ); const int numZeroRows = RawLocalLength( boundary, colShift, colStride ); MemZero( &localBuffer[jLocal*ldim], numZeroRows ); } } } else { #ifdef HAVE_OPENMP #pragma omp parallel for #endif for( int jLocal=0; jLocal<localWidth; ++jLocal ) { const int j = rowShift + jLocal*rowStride; const int firstZeroRow = j+1; const int numNonzeroRows = RawLocalLength(firstZeroRow,colShift,colStride); if( numNonzeroRows < localHeight ) { T* col = &localBuffer[numNonzeroRows+jLocal*ldim]; MemZero( col, localHeight-numNonzeroRows ); } } } #ifndef RELEASE PopCallStack(); #endif }
inline typename Base<F>::type HermitianMaxNorm( UpperOrLower uplo, const DistMatrix<F>& A ) { #ifndef RELEASE PushCallStack("internal::HermitianMaxNorm"); #endif typedef typename Base<F>::type R; if( A.Height() != A.Width() ) throw std::logic_error("Hermitian matrices must be square."); const int r = A.Grid().Height(); const int c = A.Grid().Width(); const int colShift = A.ColShift(); const int rowShift = A.RowShift(); R localMaxAbs = 0; const int localWidth = A.LocalWidth(); if( uplo == UPPER ) { for( int jLocal=0; jLocal<localWidth; ++jLocal ) { int j = rowShift + jLocal*c; int numUpperRows = LocalLength(j+1,colShift,r); for( int iLocal=0; iLocal<numUpperRows; ++iLocal ) { const R thisAbs = Abs(A.GetLocal(iLocal,jLocal)); localMaxAbs = std::max( localMaxAbs, thisAbs ); } } } else { for( int jLocal=0; jLocal<localWidth; ++jLocal ) { int j = rowShift + jLocal*c; int numStrictlyUpperRows = LocalLength(j,colShift,r); for( int iLocal=numStrictlyUpperRows; iLocal<A.LocalHeight(); ++iLocal ) { const R thisAbs = Abs(A.GetLocal(iLocal,jLocal)); localMaxAbs = std::max( localMaxAbs, thisAbs ); } } } R maxAbs; mpi::AllReduce( &localMaxAbs, &maxAbs, 1, mpi::MAX, A.Grid().VCComm() ); #ifndef RELEASE PopCallStack(); #endif return maxAbs; }
inline void Walsh( int k, DistMatrix<T,U,V>& A, bool binary ) { #ifndef RELEASE PushCallStack("Walsh"); #endif if( k < 1 ) throw std::logic_error("Walsh matrices are only defined for k>=1"); const unsigned n = 1u<<k; A.ResizeTo( n, n ); // Run an O(n^2 log n / p) algorithm based upon successive sign flips const T onValue = 1; const T offValue = ( binary ? 0 : -1 ); const unsigned localHeight = A.LocalHeight(); const unsigned localWidth = A.LocalWidth(); const unsigned colShift = A.ColShift(); const unsigned rowShift = A.RowShift(); const unsigned colStride = A.ColStride(); const unsigned rowStride = A.RowStride(); for( unsigned jLocal=0; jLocal<localWidth; ++jLocal ) { const unsigned j = rowShift + jLocal*rowStride; for( unsigned iLocal=0; iLocal<localHeight; ++iLocal ) { const unsigned i = colShift + iLocal*colStride; // Recurse on the quadtree, flipping the sign of the entry each // time we are in the bottom-right quadrant unsigned r = i; unsigned s = j; unsigned t = n; bool on = true; while( t != 1u ) { t >>= 1; if( r >= t && s >= t ) on = !on; r %= t; s %= t; } if( on ) A.SetLocal( iLocal, jLocal, onValue ); else A.SetLocal( iLocal, jLocal, offValue ); } } #ifndef RELEASE PopCallStack(); #endif }
inline void DistMatrix<T,MD,STAR,Int>::AlignWith( const DistMatrix<S,MD,STAR,N>& A ) { #ifndef RELEASE PushCallStack("[MD,* ]::AlignWith([MD,* ])"); this->AssertFreeColAlignment(); this->AssertSameGrid( A ); #endif this->Empty(); this->diagPath_ = A.diagPath_; this->colAlignment_ = A.colAlignment_; this->constrainedColAlignment_ = true; this->colShift_ = A.ColShift(); #ifndef RELEASE PopCallStack(); #endif }
inline void CauchyLike ( const std::vector<F>& r, const std::vector<F>& s, const std::vector<F>& x, const std::vector<F>& y, DistMatrix<F,U,V>& A ) { #ifndef RELEASE PushCallStack("CauchyLike"); #endif const int m = r.size(); const int n = s.size(); if( x.size() != (unsigned)m ) throw std::logic_error("x vector was the wrong length"); if( y.size() != (unsigned)n ) throw std::logic_error("y vector was the wrong length"); A.ResizeTo( m, n ); const int localHeight = A.LocalHeight(); const int localWidth = A.LocalWidth(); const int colShift = A.ColShift(); const int rowShift = A.RowShift(); const int colStride = A.ColStride(); const int rowStride = A.RowStride(); for( int jLocal=0; jLocal<localWidth; ++jLocal ) { const int j = rowShift + jLocal*rowStride; for( int iLocal=0; iLocal<localHeight; ++iLocal ) { const int i = colShift + iLocal*colStride; #ifndef RELEASE // TODO: Use tolerance instead? if( x[i] == y[j] ) { std::ostringstream msg; msg << "x[" << i << "] = y[" << j << "] (" << x[i] << ") is not allowed for Cauchy-like matrices"; throw std::logic_error( msg.str().c_str() ); } #endif A.SetLocal( iLocal, jLocal, r[i]*s[j]/(x[i]-y[j]) ); } } #ifndef RELEASE PopCallStack(); #endif }
void Filter ( const DistMatrix<T,Collect<U>(),Collect<V>()>& A, DistMatrix<T, U, V >& B ) { DEBUG_CSE AssertSameGrids( A, B ); B.Resize( A.Height(), A.Width() ); if( !B.Participating() ) return; const Int colShift = B.ColShift(); const Int rowShift = B.RowShift(); util::InterleaveMatrix ( B.LocalHeight(), B.LocalWidth(), A.LockedBuffer(colShift,rowShift), B.ColStride(), B.RowStride()*A.LDim(), B.Buffer(), 1, B.LDim() ); }
void GetMappedDiagonal ( const DistMatrix<T,U,V>& A, AbstractDistMatrix<S>& dPre, function<S(const T&)> func, Int offset ) { EL_DEBUG_CSE EL_DEBUG_ONLY(AssertSameGrids( A, dPre )) ElementalProxyCtrl ctrl; ctrl.colConstrain = true; ctrl.colAlign = A.DiagonalAlign(offset); ctrl.rootConstrain = true; ctrl.root = A.DiagonalRoot(offset); DistMatrixWriteProxy<S,S,DiagCol<U,V>(),DiagRow<U,V>()> dProx( dPre, ctrl ); auto& d = dProx.Get(); d.Resize( A.DiagonalLength(offset), 1 ); if( d.Participating() ) { const Int diagShift = d.ColShift(); const Int iStart = diagShift + Max(-offset,0); const Int jStart = diagShift + Max( offset,0); const Int colStride = A.ColStride(); const Int rowStride = A.RowStride(); const Int iLocStart = (iStart-A.ColShift()) / colStride; const Int jLocStart = (jStart-A.RowShift()) / rowStride; const Int iLocStride = d.ColStride() / colStride; const Int jLocStride = d.ColStride() / rowStride; const Int localDiagLength = d.LocalHeight(); S* dBuf = d.Buffer(); const T* ABuf = A.LockedBuffer(); const Int ldim = A.LDim(); EL_PARALLEL_FOR for( Int k=0; k<localDiagLength; ++k ) { const Int iLoc = iLocStart + k*iLocStride; const Int jLoc = jLocStart + k*jLocStride; dBuf[k] = func(ABuf[iLoc+jLoc*ldim]); } } }