void TestGemv ( El::Int height, El::Int width, El::Orientation orientation, const El::Grid& grid, bool print ) { El::DistMatrix<Field> A(grid); El::Uniform( A, height, width ); // Draw the entries of the original x and y from uniform distributions // over the complex unit ball El::DistMatrix<Field,El::VC,El::STAR> x(grid), y(grid); if( orientation == El::NORMAL ) { El::Uniform( x, width, 1 ); El::Uniform( y, height, 1 ); } else { El::Uniform( x, height, 1 ); El::Uniform( y, width, 1 ); } if( print ) { El::Print( A, "A" ); El::Print( x, "x" ); El::Print( y, "y" ); } // Run the matrix-vector product if( grid.Rank() == 0 ) El::Output("Starting Gemv (with Field=",El::TypeName<Field>(),")"); El::Timer gemvElem; gemvElem.Start(); // Form y := 3 A x + 4 y El::Gemv( orientation, Field(3), A, x, Field(4), y ); gemvElem.Stop(); if( grid.Rank() == 0 ) El::Output(" Time: ",gemvElem.Total()); if( print ) { if( orientation == El::NORMAL ) El::Print( y, "y := 3 A x + 4 y" ); else El::Print( y, "y := 3 A^H x + 4 y" ); } }
int main( int argc, char* argv[] ) { El::Environment env( argc, argv ); El::mpi::Comm comm = El::mpi::COMM_WORLD; try { typedef double Real; typedef El::Complex<Real> Scalar; const El::Int m = El::Input("--height","height of matrix",100); const El::Int n = El::Input("--width","width of matrix",100); const bool print = El::Input("--print","print matrices?",false); El::ProcessInput(); El::PrintInputReport(); El::DistMatrix<Scalar> A; El::Uniform( A, m, n ); El::Timer timer; // Compute the pseudoinverseof A (but do not overwrite A) El::DistMatrix<Scalar> pinvA( A ); if( El::mpi::Rank(comm) == 0 ) timer.Start(); El::Pseudoinverse( pinvA ); if( El::mpi::Rank(comm) == 0 ) timer.Stop(); if( print ) { El::Print( A, "A" ); El::Print( pinvA, "pinv(A)" ); } const Real frobA = El::FrobeniusNorm( A ); const Real frobPinvA = El::FrobeniusNorm( pinvA ); if( El::mpi::Rank(comm) == 0 ) { El::Output("PseudoInverse time: ",timer.Total()," secs"); El::Output ("|| A ||_F = ",frobA,"\n", "|| pinv(A) ||_F = ",frobPinvA,"\n"); } } catch( std::exception& e ) { El::ReportException(e); } return 0; }
int main( int argc, char* argv[] ) { El::Environment env( argc, argv ); El::mpi::Comm comm = El::mpi::COMM_WORLD; const int commRank = El::mpi::Rank( comm ); const int commSize = El::mpi::Size( comm ); try { typedef double Real; typedef El::Complex<Real> Scalar; const El::Int n = El::Input("--size","size of matrix",100); const El::Int numRhs = El::Input("--numRhs","# of right-hand sides",1); const El::Int blocksize = El::Input("--blocksize","algorithmic blocksize",64); const El::Int numTests = El::Input("--numTests","number of tests",3); const bool error = El::Input("--error","test Elemental error?",true); El::Int gridHeight = El::Input("--gridHeight","grid height",0); const bool details = El::Input("--details","print norm details?",false); const bool print = El::Input("--print","print matrices?",false); El::ProcessInput(); El::PrintInputReport(); El::SetBlocksize( blocksize ); // If the grid height wasn't specified, then we should attempt to build // a nearly-square process grid if( gridHeight == 0 ) gridHeight = El::Grid::FindFactor( commSize ); El::Grid grid( comm, gridHeight ); if( commRank == 0 ) El::Output("Grid is: ",grid.Height()," x ",grid.Width()); // Set up random A and B, then make the copies X := B El::Timer timer; El::DistMatrix<Scalar> A(grid), B(grid), X(grid); for( El::Int test=0; test<numTests; ++test ) { El::Uniform( A, n, n ); El::Uniform( B, n, numRhs ); X = B; if( print ) { El::Print( A, "A" ); El::Print( B, "B" ); } // Perform the LU factorization and simultaneous solve if( commRank == 0 ) El::Output("Starting Elemental linear solve"); El::mpi::Barrier( comm ); if( commRank == 0 ) timer.Start(); El::LinearSolve( A, X ); El::mpi::Barrier( comm ); if( commRank == 0 ) El::Output(timer.Stop()," seconds"); if( error ) { // Form R := A X - B auto R( B ); El::Gemm ( El::NORMAL, El::NORMAL, Scalar(1), A, X, Scalar(-1), R ); // Compute infinity norms and a relative residual const Real eps = El::limits::Epsilon<Real>(); const Real AInfNorm = El::InfinityNorm( A ); const Real BInfNorm = El::InfinityNorm( B ); const Real XInfNorm = El::InfinityNorm( X ); const Real RInfNorm = El::InfinityNorm( R ); const Real infResidual = RInfNorm / (AInfNorm*XInfNorm*eps*n); if( commRank == 0 ) { if( details ) { El::Output(""); El::Output("||A||_oo = ",AInfNorm); El::Output("||B||_oo = ",BInfNorm); El::Output("||X||_oo = ",XInfNorm); El::Output("||A X - B||_oo = ",RInfNorm); } El::Output ("||A X - B||_oo / (||A||_oo ||X||_oo eps n) = ", infResidual); } // Compute one norms and a relative residual const Real AOneNorm = El::OneNorm( A ); const Real BOneNorm = El::OneNorm( B ); const Real XOneNorm = El::OneNorm( X ); const Real ROneNorm = El::OneNorm( R ); const Real oneResidual = ROneNorm / (AOneNorm*XOneNorm*eps*n); if( commRank == 0 ) { if( details ) { El::Output(""); El::Output("||A||_1 = ",AOneNorm); El::Output("||B||_1 = ",BOneNorm); El::Output("||X||_1 = ",XOneNorm); El::Output("||A X - B||_1 = ",ROneNorm); } El::Output ("||A X - B||_1 / (||A||_1 ||X||_1 eps n) = ", oneResidual,"\n"); } } } } catch( std::exception& e ) { El::ReportException(e); } return 0; }
int main( int argc, char* argv[] ) { El::Environment env( argc, argv ); try { typedef double Real; typedef El::Complex<Real> Scalar; const El::Int m = El::Input("--height","height of matrix",20); const El::Int n = El::Input("--width","width of matrix",100); const El::Int r = El::Input("--rank","rank of matrix",5); const El::Int maxSteps = El::Input("--maxSteps","max # of steps of QR",10); const Real tol = El::Input("--tol","tolerance for ID",Real(-1)); const bool print = El::Input("--print","print matrices?",false); const bool smallestFirst = El::Input("--smallestFirst","smallest norm first?",false); El::ProcessInput(); El::PrintInputReport(); El::mpi::Comm comm = El::mpi::COMM_WORLD; const El::Grid& grid = El::Grid::Default(); El::DistMatrix<Scalar> U(grid), V(grid), A(grid); El::Uniform( U, m, r ); El::Uniform( V, n, r ); El::Gemm( El::NORMAL, El::ADJOINT, Scalar(1), U, V, A ); const Real frobA = El::FrobeniusNorm( A ); if( print ) El::Print( A, "A" ); El::DistPermutation Omega(grid); El::DistMatrix<Scalar,El::STAR,El::VR> Z(grid); El::QRCtrl<Real> ctrl; ctrl.boundRank = true; ctrl.maxRank = maxSteps; if( tol != -1. ) { ctrl.adaptive = true; ctrl.tol = tol; } ctrl.smallestFirst = smallestFirst; El::Timer timer; if( El::mpi::Rank(comm) == 0 ) timer.Start(); El::ID( A, Omega, Z, ctrl ); if( El::mpi::Rank(comm) == 0 ) timer.Stop(); const El::Int rank = Z.Height(); if( print ) { El::DistMatrix<El::Int> OmegaFull(grid); Omega.ExplicitMatrix( OmegaFull ); El::Print( OmegaFull, "Omega" ); El::Print( Z, "Z" ); } // Pivot A and form the matrix of its (hopefully) dominant columns El::Timer permTimer("permTimer"); permTimer.Start(); Omega.PermuteCols( A ); permTimer.Stop(); auto hatA( A ); hatA.Resize( m, rank ); if( print ) { El::Print( A, "A Omega^T" ); El::Print( hatA, "\\hat{A}" ); } // Check || A Omega^T - \hat{A} [I, Z] ||_F / || A ||_F El::DistMatrix<Scalar> AL(grid), AR(grid); El::PartitionRight( A, AL, AR, rank ); El::Zero( AL ); { El::DistMatrix<Scalar,El::MC,El::STAR> hatA_MC_STAR(grid); El::DistMatrix<Scalar,El::STAR,El::MR> Z_STAR_MR(grid); hatA_MC_STAR.AlignWith( AR ); Z_STAR_MR.AlignWith( AR ); hatA_MC_STAR = hatA; Z_STAR_MR = Z; El::LocalGemm ( El::NORMAL, El::NORMAL, Scalar(-1), hatA_MC_STAR, Z_STAR_MR, Scalar(1), AR ); } const Real frobError = El::FrobeniusNorm( A ); if( print ) El::Print( A, "A Omega^T - \\hat{A} [I, Z]" ); if( El::mpi::Rank(comm) == 0 ) { El::Output(" ID time: ",timer.Total()," secs"); El::Output ("|| A ||_F = ",frobA,"\n", "|| A Omega^T - \\hat{A} [I, Z] ||_F / || A ||_F = ", frobError/frobA); } } catch( std::exception& e ) { El::ReportException(e); } return 0; }
int main( int argc, char* argv[] ) { El::Environment env( argc, argv ); try { const El::Int n = El::Input("--n","problem size",200); const El::Int maxIter = El::Input("--maxIter","maximum # of iter's",500); const Real lb = El::Input("--lb","lower bound for x",0.5); const Real ub = El::Input("--ub","upper bound for x",1.0); const Real lbEig = El::Input("--lbEig","spectral lower bound",1.); const Real ubEig = El::Input("--ubEig","spectral upper bound",2.); const Real rho = El::Input("--rho","augmented Lagrangian param.",1.); const Real alpha = El::Input("--alpha","over-relaxation",1.2); const Real absTol = El::Input("--absTol","absolute tolerance",1e-6); const Real relTol = El::Input("--relTol","relative tolerance",1e-4); const bool inv = El::Input("--inv","form inv(LU) to avoid trsv?",true); const bool progress = El::Input("--progress","print progress?",true); const bool display = El::Input("--display","display matrices?",false); const bool print = El::Input("--print","print matrices",false); El::ProcessInput(); El::PrintInputReport(); El::ADMMCtrl<Real> ctrl; ctrl.rho = rho; ctrl.alpha = alpha; ctrl.maxIter = maxIter; ctrl.absTol = absTol; ctrl.relTol = relTol; ctrl.inv = inv; ctrl.print = progress; El::DistMatrix<Real> Q, c, xTrue; El::HermitianUniformSpectrum( Q, n, lbEig, ubEig ); // Alternate the entries of xTrue between ub and lb El::Zeros( xTrue, n, 1 ); if( xTrue.LocalWidth() == 1 ) for( El::Int iLoc=0; iLoc<xTrue.LocalHeight(); ++iLoc ) xTrue.SetLocal( iLoc, 0, ( xTrue.GlobalRow(iLoc)%2==0 ? lb : ub ) ); // Set c := - Q xTrue - du + dl El::Zeros( c, n, 1 ); El::Hemv( El::LOWER, Real(-1), Q, xTrue, Real(0), c ); if( c.LocalWidth() == 1 ) for( El::Int iLoc=0; iLoc<c.LocalHeight(); ++iLoc ) c.UpdateLocal( iLoc, 0, ( c.GlobalRow(iLoc)%2==0 ? 0.5 : -0.5 ) ); if( print ) { El::Print( Q, "Q" ); El::Print( c, "c" ); El::Print( xTrue, "xTrue" ); } if( display ) El::Display( Q, "Q" ); El::Timer timer; El::DistMatrix<Real> z; if( El::mpi::Rank() == 0 ) timer.Start(); El::qp::box::ADMM( Q, c, lb, ub, z, ctrl ); if( El::mpi::Rank() == 0 ) timer.Stop(); if( print ) El::Print( z, "z" ); if( El::mpi::Rank() == 0 ) El::Output("QPBox time: ",timer.Total(),"secs"); } catch( std::exception& e ) { El::ReportException(e); } return 0; }
int main( int argc, char* argv[] ) { El::Environment env( argc, argv ); El::mpi::Comm comm = El::mpi::COMM_WORLD; const int commRank = El::mpi::Rank( comm ); try { typedef double Real; typedef El::Complex<Real> Scalar; El::Timer timer; const El::Int n1 = El::Input("--n1","first grid dimension",30); const El::Int n2 = El::Input("--n2","second grid dimension",30); const El::Int n3 = El::Input("--n3","third grid dimension",30); const Real omega = El::Input("--omega","angular frequency",Real(18)); const Real damping = El::Input("--damping","damping parameter",Real(7)); const bool selInv = El::Input("--selInv","selectively invert?",false); const bool intraPiv = El::Input("--intraPiv","frontal pivoting?",false); const bool natural = El::Input("--natural","analytic partitions?",true); const bool sequential = El::Input ("--sequential","sequential partitions?",true); const int numDistSeps = El::Input ("--numDistSeps", "number of separators to try per distributed partition",1); const int numSeqSeps = El::Input ("--numSeqSeps", "number of separators to try per sequential partition",1); const int cutoff = El::Input("--cutoff","cutoff for nested dissection",128); const bool print = El::Input("--print","print matrix?",false); const bool display = El::Input("--display","display matrix?",false); El::ProcessInput(); const El::Grid grid(comm); El::DistSparseMatrix<Scalar> A(grid); Scalar dampedOmega( omega, damping ); El::Helmholtz( A, n1, n2, n3, dampedOmega*dampedOmega ); const El::Int N = A.Height(); if( display ) El::Display( A, "A" ); if( print ) El::Print( A, "A" ); if( commRank == 0 ) El::Output("Generating random vector x and forming y := A x"); timer.Start(); El::DistMultiVec<Scalar> x( N, 1, grid ), y( N, 1, grid ); El::MakeUniform( x ); El::Zero( y ); El::Multiply( El::NORMAL, Scalar(1), A, x, Scalar(0), y ); const Real yOrigNorm = El::FrobeniusNorm( y ); El::mpi::Barrier(comm); if( commRank == 0 ) El::Output(timer.Stop()," seconds"); El::BisectCtrl ctrl; ctrl.sequential = sequential; ctrl.numSeqSeps = numSeqSeps; ctrl.numDistSeps = numDistSeps; ctrl.cutoff = cutoff; El::DistSparseLDLFactorization<Scalar> sparseLDLFact; const bool hermitian = false; if( commRank == 0 ) El::Output("Running analysis..."); timer.Start(); if( natural ) { sparseLDLFact.Initialize3DGridGraph ( n1, n2, n3, A, hermitian, ctrl ); } else { sparseLDLFact.Initialize( A, hermitian, ctrl ); } El::mpi::Barrier(comm); if( commRank == 0 ) El::Output(timer.Stop()," seconds"); auto& front = sparseLDLFact.Front(); auto& info = sparseLDLFact.NodeInfo(); const El::Int rootSepSize = info.size; if( commRank == 0 ) El::Output(rootSepSize," vertices in root separator\n"); if( commRank == 0 ) El::Output("Running LDL factorization..."); El::mpi::Barrier(comm); timer.Start(); El::LDLFrontType type; if( intraPiv ) type = selInv ? El::LDL_INTRAPIV_SELINV_2D : El::LDL_INTRAPIV_2D; else type = selInv ? El::LDL_SELINV_2D : El::LDL_2D; sparseLDLFact.Factor( type ); El::mpi::Barrier(comm); if( commRank == 0 ) El::Output(timer.Stop()," seconds"); if( info.child != nullptr && info.child->onLeft ) { if( commRank == 0 ) El::Output ("Computing SVD of connectivity of second separator to " "the root separator..."); timer.Start(); const auto& FL = front.child->L2D; const El::Grid& grid = FL.Grid(); const El::Int height = FL.Height(); const El::Int width = FL.Width(); auto B = FL( El::IR(width,height), El::IR(0,width) ); El::DistMatrix<Real,El::VR,El::STAR> singVals_VR_STAR( grid ); El::SVD( B, singVals_VR_STAR ); El::DistMatrix<Real,El::CIRC,El::CIRC> singVals( singVals_VR_STAR ); El::mpi::Barrier( grid.Comm() ); const Real twoNorm = El::MaxNorm( singVals_VR_STAR ); const El::Int minDim = singVals_VR_STAR.Height(); if( grid.Rank() == singVals.Root() ) { El::Output (" two-norm is ",twoNorm," (took ",timer.Stop()," seconds)"); for( Real tol=1e-1; tol>=Real(1e-10); tol/=10 ) { El::Int numRank = minDim; for( El::Int j=0; j<minDim; ++j ) { if( singVals.GetLocal(j,0) <= twoNorm*tol ) { numRank = j; break; } } El::Output(" rank (",tol,")=",numRank,"/",minDim); } } } if( commRank == 0 ) El::Output ("Computing SVD of the largest off-diagonal block of " "numerical Green's function on root separator..."); { timer.Start(); const auto& FL = front.L2D; const El::Grid& grid = FL.Grid(); const El::Int lHalf = rootSepSize/2; const El::Int uHalf = rootSepSize - lHalf; if( commRank == 0 ) El::Output("lower half=",lHalf,", upper half=",uHalf); auto offDiagBlock = FL( El::IR(lHalf,rootSepSize), El::IR(0,lHalf) ); El::DistMatrix<Real,El::VR,El::STAR> singVals_VR_STAR( grid ); El::SVD( offDiagBlock, singVals_VR_STAR ); El::DistMatrix<Real,El::CIRC,El::CIRC> singVals( singVals_VR_STAR ); El::mpi::Barrier( grid.Comm() ); const Real twoNorm = El::MaxNorm( singVals_VR_STAR ); if( grid.Rank() == singVals.Root() ) { El::Output(timer.Stop()," seconds"); for( Real tol=1e-1; tol>=Real(1e-10); tol/=10 ) { El::Int numRank = lHalf; for( El::Int j=0; j<lHalf; ++j ) { if( singVals.GetLocal(j,0) <= twoNorm*tol ) { numRank = j; break; } } El::Output(" rank (",tol,")=",numRank,"/",lHalf); } } } if( commRank == 0 ) El::Output("Solving against y..."); timer.Start(); sparseLDLFact.Solve( y ); El::mpi::Barrier(comm); if( commRank == 0 ) El::Output(timer.Stop()," seconds"); if( commRank == 0 ) El::Output("Checking error in computed solution..."); const Real xNorm = El::FrobeniusNorm( x ); const Real yNorm = El::FrobeniusNorm( y ); y -= x; const Real errorNorm = El::FrobeniusNorm( y ); if( commRank == 0 ) El::Output ("|| x ||_2 = ",xNorm,"\n", "|| xComp ||_2 = ",yNorm,"\n", "|| A x ||_2 = ",yOrigNorm,"\n", "|| error ||_2 / || x ||_2 = ",errorNorm/xNorm,"\n", "|| error ||_2 / || A x ||_2 = ",errorNorm/yOrigNorm); } catch( std::exception& e ) { El::ReportException(e); } return 0; }
int main( int argc, char* argv[] ) { El::Environment env( argc, argv ); try { const El::Int m = El::Input("--m","height of matrix",100); const El::Int n = El::Input("--n","width of matrix",200); // TODO(poulson): Add options for controlling IPM const El::Int maxIter = El::Input("--maxIter","maximum # of iter's",500); const Real lambda = El::Input("--lambda","DS parameter",0.5); const bool display = El::Input("--display","display matrices?",false); const bool print = El::Input("--print","print matrices",false); El::ProcessInput(); El::PrintInputReport(); El::SparseMatrix<Real> A; El::Matrix<Real> b, xTrue; El::Identity( A, m, n ); El::Uniform( b, m, 1 ); if( print ) { El::Print( A, "A" ); El::Print( b, "b" ); } if( display ) El::Display( A, "A" ); El::lp::affine::Ctrl<Real> affineCtrl; affineCtrl.mehrotraCtrl.print = true; El::Matrix<Real> x; El::Timer timer; if( El::mpi::Rank() == 0 ) timer.Start(); El::DS( A, b, lambda, x, affineCtrl ); if( El::mpi::Rank() == 0 ) timer.Stop(); if( print ) El::Print( x, "x" ); const El::Int xZeroNorm = El::ZeroNorm( x ); if( El::mpi::Rank() == 0 ) { El::Output("Dantzig Selector time: ",timer.Total()," secs"); El::Output("|| x ||_0 = ",xZeroNorm); } SoftThreshold( x, El::Sqrt(El::limits::Epsilon<Real>()) ); if( print ) El::Print( x, "xThresh" ); const El::Int xZeroNormThresh = El::ZeroNorm( x ); if( El::mpi::Rank() == 0 ) { El::Output("|| xThresh ||_0 = ",xZeroNormThresh); } } catch( std::exception& e ) { El::ReportException(e); } return 0; }
int main( int argc, char* argv[] ) { El::Environment env( argc, argv ); try { const El::Int n = El::Input("--size","width of matrix",100); const bool display = El::Input("--display","display matrices?",false); const bool print = El::Input("--print","print matrices?",false); const bool smallestFirst = El::Input("--smallestFirst","smallest norm first?",false); El::ProcessInput(); El::PrintInputReport(); const El::Int m = n; El::QRCtrl<double> ctrl; ctrl.smallestFirst = smallestFirst; El::DistMatrix<El::Complex<double>> A; El::GKS( A, n ); const double frobA = El::FrobeniusNorm( A ); if( display ) El::Display( A, "A" ); if( print ) El::Print( A, "A" ); // Compute the pivoted QR decomposition of A, but do not overwrite A auto QRPiv( A ); El::DistMatrix<El::Complex<double>> householderScalarsPiv; El::DistMatrix<double> signaturePiv; El::DistPermutation Omega; El::Timer PQRtimer; if( El::mpi::Rank() == 0 ) PQRtimer.Start(); El::QR( QRPiv, householderScalarsPiv, signaturePiv, Omega ); if( El::mpi::Rank() == 0 ) PQRtimer.Stop(); if( display ) { El::Display( QRPiv, "QRPiv" ); El::Display( householderScalarsPiv, "householderScalarsPiv" ); El::Display( signaturePiv, "signaturePiv" ); El::DistMatrix<El::Int> OmegaFull; Omega.ExplicitMatrix( OmegaFull ); El::Display( OmegaFull, "Omega" ); } if( print ) { El::Print( QRPiv, "QRPiv" ); El::Print( householderScalarsPiv, "householderScalarsPiv" ); El::Print( signaturePiv, "signaturePiv" ); El::DistMatrix<El::Int> OmegaFull; Omega.ExplicitMatrix( OmegaFull ); El::Print( OmegaFull, "Omega" ); } // Compute the standard QR decomposition of A auto QRNoPiv( A ); El::DistMatrix<El::Complex<double>> householderScalarsNoPiv; El::DistMatrix<double> signatureNoPiv; El::Timer QRtimer; if( El::mpi::Rank() == 0 ) QRtimer.Start(); El::QR( QRNoPiv, householderScalarsNoPiv, signatureNoPiv ); if( El::mpi::Rank() == 0 ) QRtimer.Start(); if( display ) { El::Display( QRNoPiv, "QRNoPiv" ); El::Display( householderScalarsNoPiv, "householderScalarsNoPiv" ); El::Display( signatureNoPiv, "signatureNoPiv" ); } if( print ) { El::Print( QRNoPiv, "QRNoPiv" ); El::Print( householderScalarsNoPiv, "householderScalarsNoPiv" ); El::Print( signatureNoPiv, "signatureNoPiv" ); } // Check the error in the pivoted QR factorization, // || A Omega^T - Q R ||_F / || A ||_F auto E( QRPiv ); El::MakeTrapezoidal( El::UPPER, E ); El::qr::ApplyQ ( El::LEFT, El::NORMAL, QRPiv, householderScalarsPiv, signaturePiv, E ); Omega.InversePermuteCols( E ); E -= A; const double frobQRPiv = El::FrobeniusNorm( E ); if( display ) El::Display( E, "A P - Q R" ); if( print ) El::Print( E, "A P - Q R" ); // Check the error in the standard QR factorization, // || A - Q R ||_F / || A ||_F E = QRNoPiv; El::MakeTrapezoidal( El::UPPER, E ); El::qr::ApplyQ ( El::LEFT, El::NORMAL, QRNoPiv, householderScalarsNoPiv, signatureNoPiv, E ); E -= A; const double frobQRNoPiv = El::FrobeniusNorm( E ); if( display ) El::Display( E, "A - Q R" ); if( print ) El::Print( E, "A - Q R" ); // Check orthogonality of pivoted Q, || I - Q^H Q ||_F / || A ||_F El::Identity( E, m, n ); El::qr::ApplyQ ( El::LEFT, El::NORMAL, QRPiv, householderScalarsPiv, signaturePiv, E ); El::qr::ApplyQ ( El::LEFT, El::ADJOINT, QRPiv, householderScalarsPiv, signaturePiv, E ); const El::Int k = El::Min(m,n); auto EUpper = E( El::IR(0,k), El::IR(0,k) ); El::ShiftDiagonal( EUpper, El::Complex<double>(-1) ); const double frobOrthogPiv = El::FrobeniusNorm( EUpper ); if( display ) El::Display( E, "pivoted I - Q^H Q" ); if( print ) El::Print( E, "pivoted I - Q^H Q" ); // Check orthogonality of unpivoted Q, || I - Q^H Q ||_F / || A ||_F El::Identity( E, m, n ); El::qr::ApplyQ ( El::LEFT, El::NORMAL, QRPiv, householderScalarsPiv, signaturePiv, E ); El::qr::ApplyQ ( El::LEFT, El::ADJOINT, QRPiv, householderScalarsPiv, signaturePiv, E ); EUpper = E( El::IR(0,k), El::IR(0,k) ); El::ShiftDiagonal( EUpper, El::Complex<double>(-1) ); const double frobOrthogNoPiv = El::FrobeniusNorm( EUpper ); if( display ) El::Display( E, "unpivoted I - Q^H Q" ); if( print ) El::Print( E, "unpivoted I - Q^H Q" ); if( El::mpi::Rank() == 0 ) { El::Output("Pivot QR time: ",PQRtimer.Total()," secs\n", " QR time: ",QRtimer.Total()," secs"); El::Output ("|| A ||_F = ",frobA,"\n\n", "With pivoting: \n", " || A P - Q R ||_F / || A ||_F = ",frobQRPiv/frobA,"\n", " || I - Q^H Q ||_F / || A ||_F = ",frobOrthogPiv/frobA,"\n\n", "Without pivoting: \n", " || A - Q R ||_F / || A ||_F = ",frobQRNoPiv/frobA,"\n", " || I - Q^H Q ||_F / || A ||_F = ",frobOrthogNoPiv/frobA,"\n"); } } catch( std::exception& e ) { El::ReportException(e); } return 0; }
int main( int argc, char* argv[] ) { El::Environment env( argc, argv ); try { El::Int gridHeight = El::Input("--gridHeight","process grid height",0); const bool colMajor = El::Input("--colMajor","column-major ordering?",true); const El::Int matType = El::Input("--matType","0:uniform,\n" "1:Haar,\n" "2:Lotkin,\n" "3:Grcar,\n" "4:FoxLi,\n" "5:HelmholtzPML1D,\n" "6:HelmholtzPML2D,\n" "7:TrefethenEmbree,\n" "8:Bull's head,\n" "9:Triangle,\n" "10:Whale,\n" "11:UniformHelmholtzGreen's,\n" "12:HatanoNelson,\n" "13:EhrenfestDecay,\n" "14:RiffleDecay\n" "15:Jordan\n",4); const El::Int normInt = El::Input("--norm","0:two norm,1:one norm",0); const El::Int n = El::Input("--size","height of matrix",100); const El::Int nbAlg = El::Input("--nbAlg","algorithmic blocksize",96); // QR algorithm options const El::Int nbDist = El::Input("--nbDist","distribution blocksize",32); // Spectral Divide and Conquer options const bool sdc = El::Input("--sdc","use Spectral D&C?",false); const El::Int cutoff = El::Input("--cutoff","problem size for QR",256); const El::Int maxInnerIts = El::Input("--maxInnerIts","SDC limit",2); const El::Int maxOuterIts = El::Input("--maxOuterIts","SDC limit",10); const bool random = El::Input("--random","Random RRQR in SDC",true); const double sdcTol = El::Input("--sdcTol","Rel. tol. for SDC",1e-6); const double spreadFactor = El::Input("--spreadFactor","median pert.",1e-6); const double signTol = El::Input("--signTol","Sign tolerance for SDC",1e-9); const double realCenter = El::Input("--realCenter","real center",0.); const double imagCenter = El::Input("--imagCenter","imag center",0.); double realWidth = El::Input("--realWidth","x width of image",0.); double imagWidth = El::Input("--imagWidth","y width of image",0.); const El::Int numReal = El::Input("--numReal","num real chunks",2); const El::Int numImag = El::Input("--numImag","num imag chunks",2); const El::Int realSize = El::Input("--realSize","number of x samples",100); const El::Int imagSize = El::Input("--imagSize","number of y samples",100); const bool arnoldi = El::Input("--arnoldi","use Arnoldi?",true); const El::Int basisSize = El::Input("--basisSize","num basis vectors",10); const El::Int maxIts = El::Input("--maxIts","maximum pseudospec iter's",200); const double psTol = El::Input("--psTol","tolerance for pseudospectra",1e-6); // Uniform options const double uniformRealCenter = El::Input("--uniformRealCenter","real center of uniform dist",0.); const double uniformImagCenter = El::Input("--uniformImagCenter","imag center of uniform dist",0.); const double uniformRadius = El::Input("--uniformRadius","radius of uniform dist",1.); // Grcar options const El::Int numBands = El::Input("--numBands","num bands for Grcar",3); // Fox-Li options const double omega = El::Input("--omega","frequency for Fox-Li/Helm",16*M_PI); // Helmholtz-PML options [also uses omega from Fox-Li] const El::Int mx = El::Input("--mx","number of x points for HelmholtzPML",30); const El::Int my = El::Input("--my","number of y points for HelmholtzPML",30); const El::Int numPmlPoints = El::Input("--numPml","num PML points for Helm",5); const double sigma = El::Input("--sigma","PML amplitude",1.5); const double pmlExp = El::Input("--pmlExp","PML takeoff exponent",3.); // Uniform Helmholtz Green's options const double lambda = El::Input("--lambda","wavelength of U.H.Green's",0.1); // Hatano-Nelson options const double gHatano = El::Input("--gHatano","g in Hatano-Nelson",0.5); const bool periodic = El::Input("--periodic","periodic HatanoNelson?",true); // Input/Output options const bool progress = El::Input("--progress","print progress?",true); const bool deflate = El::Input("--deflate","deflate?",true); const bool display = El::Input("--display","display matrices?",false); const bool write = El::Input("--write","write matrices?",false); const bool saveSchur = El::Input("--saveSchur","save Schur factor?",true); const El::Int numSaveFreq = El::Input("--numSaveFreq","numerical save frequency",-1); const El::Int imgSaveFreq = El::Input("--imgSaveFreq","image save frequency",-1); const El::Int imgDispFreq = El::Input("--imgDispFreq","image display frequency",-1); const std::string numBase = El::Input("--numBase","numerical save basename",std::string("num")); const std::string imgBase = El::Input("--imgBase","image save basename",std::string("img")); const El::Int numFormatInt = El::Input("--numFormat","numerical format",2); const El::Int imgFormatInt = El::Input("--imgFormat","image format",8); const El::Int colorMapInt = El::Input("--colorMap","color map",0); const bool itCounts = El::Input("--itCounts","display iter. counts?",true); El::ProcessInput(); El::PrintInputReport(); El::mpi::Comm comm = El::mpi::COMM_WORLD; if( gridHeight == 0 ) gridHeight = El::Grid::DefaultHeight( El::mpi::Size(comm) ); const El::GridOrder order = colMajor ? El::COLUMN_MAJOR : El::ROW_MAJOR; const El::Grid grid( comm, gridHeight, order ); El::SetBlocksize( nbAlg ); if( normInt < 0 || normInt > 1 ) El::LogicError("Invalid pseudospec norm type"); if( numFormatInt < 1 || numFormatInt >= El::FileFormat_MAX ) El::LogicError ("Invalid numerical format integer, should be in [1,", El::FileFormat_MAX,")"); if( imgFormatInt < 1 || imgFormatInt >= El::FileFormat_MAX ) El::LogicError ("Invalid image format integer, should be in [1,", El::FileFormat_MAX,")"); const auto psNorm = static_cast<El::PseudospecNorm>(normInt); const auto numFormat = static_cast<El::FileFormat>(numFormatInt); const auto imgFormat = static_cast<El::FileFormat>(imgFormatInt); const auto colorMap = static_cast<El::ColorMap>(colorMapInt); El::SetColorMap( colorMap ); const El::Complex<double> center(realCenter,imagCenter), uniformCenter(uniformRealCenter,uniformImagCenter); bool isReal = true; std::string matName; El::DistMatrix<double> AReal(grid); El::DistMatrix<El::Complex<double>> ACpx(grid); switch( matType ) { case 0: matName="uniform"; El::Uniform( ACpx, n, n, uniformCenter, uniformRadius ); isReal = false; break; case 1: matName="Haar"; El::Haar( ACpx, n ); isReal = false; break; case 2: matName="Lotkin"; El::Lotkin( AReal, n ); isReal = true; break; case 3: matName="Grcar"; El::Grcar( AReal, n, numBands ); isReal = true; break; case 4: matName="FoxLi"; El::FoxLi( ACpx, n, omega ); isReal = false; break; case 5: matName="HelmholtzPML"; El::HelmholtzPML ( ACpx, n, El::Complex<double>(omega), numPmlPoints, sigma, pmlExp ); isReal = false; break; case 6: matName="HelmholtzPML2D"; El::HelmholtzPML ( ACpx, mx, my, El::Complex<double>(omega), numPmlPoints, sigma, pmlExp ); isReal = false; break; case 7: matName="TrefethenEmbree"; El::TrefethenEmbree( ACpx, n ); isReal = false; break; case 8: matName="BullsHead"; El::BullsHead( ACpx, n ); isReal = false; break; case 9: matName="Triangle"; El::Triangle( AReal, n ); isReal = true; break; case 10: matName="Whale"; El::Whale( ACpx, n ); isReal = false; break; case 11: matName="UniformHelmholtzGreens"; El::UniformHelmholtzGreens( ACpx, n, lambda ); isReal = false; break; case 12: matName="HatanoNelson"; El::HatanoNelson ( AReal, n, realCenter, uniformRadius, gHatano, periodic ); isReal = true; break; case 13: matName="EhrenfestDecay"; // Force the complex matrix to allow for one-norm pseudospectra El::EhrenfestDecay( ACpx, n ); isReal = false; break; case 14: matName="RiffleDecay"; // Force the complex matrix to allow for one-norm pseudospectra El::RiffleDecay( ACpx, n ); isReal = false; break; case 15: matName="Jordan"; El::Jordan( AReal, n, 0. ); isReal = true; break; default: El::LogicError("Invalid matrix type"); } if( display ) { if( isReal ) El::Display( AReal, "A" ); else El::Display( ACpx, "A" ); } if( write ) { if( isReal ) { El::Write( AReal, "A", numFormat ); El::Write( AReal, "A", imgFormat ); } else { El::Write( ACpx, "A", numFormat ); El::Write( ACpx, "A", imgFormat ); } } // Begin by computing the Schur decomposition El::Timer timer; El::DistMatrix<El::Complex<double>> w(grid); El::mpi::Barrier( comm ); const bool formATR = true; El::DistMatrix<double> QReal(grid); El::DistMatrix<El::Complex<double>> QCpx(grid); El::SchurCtrl<double> ctrl; ctrl.hessSchurCtrl.fullTriangle = formATR; ctrl.hessSchurCtrl.blockHeight = nbDist; ctrl.hessSchurCtrl.scalapack = false; ctrl.useSDC = sdc; // Spectral D&C options (only relevant if 'sdc' is true) ctrl.sdcCtrl.cutoff = cutoff; ctrl.sdcCtrl.maxInnerIts = maxInnerIts; ctrl.sdcCtrl.maxOuterIts = maxOuterIts; ctrl.sdcCtrl.tol = sdcTol; ctrl.sdcCtrl.spreadFactor = spreadFactor; ctrl.sdcCtrl.random = random; ctrl.sdcCtrl.progress = progress; ctrl.sdcCtrl.signCtrl.tol = signTol; ctrl.sdcCtrl.signCtrl.progress = progress; timer.Start(); if( isReal ) { if( psNorm == El::PS_TWO_NORM ) El::Schur( AReal, w, ctrl ); else El::Schur( AReal, w, QReal, ctrl ); } else { if( psNorm == El::PS_TWO_NORM ) El::Schur( ACpx, w, ctrl ); else El::Schur( ACpx, w, QCpx, ctrl ); } El::mpi::Barrier( comm ); const double schurTime = timer.Stop(); if( El::mpi::Rank(comm) == 0 ) El::Output("Schur decomposition took ",schurTime," seconds"); if( saveSchur ) { if( El::mpi::Rank(comm) == 0 ) El::Output("Writing Schur decomposition to file..."); timer.Start(); if( isReal ) { auto schurTitle = El::BuildString (matName,"_",AReal.ColStride(),"x",AReal.RowStride(), "_",AReal.DistRank()); El::Write( AReal.LockedMatrix(), schurTitle, El::BINARY ); if( psNorm == El::PS_ONE_NORM ) { auto QTitle = El::BuildString (matName,"_Q_",QReal.ColStride(),"x",QReal.RowStride(), "_",QReal.DistRank()); El::Write( QReal.LockedMatrix(), QTitle, El::BINARY ); } } else { auto schurTitle = El::BuildString (matName,"_",ACpx.ColStride(),"x",ACpx.RowStride(), "_",ACpx.DistRank()); El::Write( ACpx.LockedMatrix(), schurTitle, El::BINARY ); if( psNorm == El::PS_ONE_NORM ) { auto QTitle = El::BuildString (matName,"_Q_",QCpx.ColStride(),"x",QCpx.RowStride(), "_",QCpx.DistRank()); El::Write( QCpx.LockedMatrix(), QTitle, El::BINARY ); } } El::mpi::Barrier( comm ); const double saveSchurTime = timer.Stop(); if( El::mpi::Rank(comm) == 0 ) El::Output("Saving took ",saveSchurTime," seconds"); } // Find a window if none is specified if( realWidth == 0. || imagWidth == 0. ) { const double radius = El::MaxNorm( w ); const double oneNorm = isReal ? El::OneNorm(AReal) : El::OneNorm(ACpx); double width; if( oneNorm == 0. && radius == 0. ) { width = 1; if( El::mpi::Rank(comm) == 0 ) El::Output("Setting width to 1 to handle zero matrix"); } else if( radius >= 0.2*oneNorm ) { width = 2.5*radius; if( El::mpi::Rank(comm) == 0 ) El::Output ("Setting width to ",width, " based on the spectral radius, ",radius); } else { width = 0.8*oneNorm; if( El::mpi::Rank(comm) == 0 ) El::Output ("Setting width to ",width," based on the one norm, ", oneNorm); } realWidth = width; imagWidth = width; } El::PseudospecCtrl<double> psCtrl; psCtrl.norm = psNorm; psCtrl.schur = true; psCtrl.maxIts = maxIts; psCtrl.tol = psTol; psCtrl.deflate = deflate; psCtrl.arnoldi = arnoldi; psCtrl.basisSize = basisSize; psCtrl.progress = progress; psCtrl.snapCtrl.imgSaveFreq = imgSaveFreq; psCtrl.snapCtrl.numSaveFreq = numSaveFreq; psCtrl.snapCtrl.imgDispFreq = imgDispFreq; psCtrl.snapCtrl.imgFormat = imgFormat; psCtrl.snapCtrl.numFormat = numFormat; psCtrl.snapCtrl.itCounts = itCounts; // Visualize/write the pseudospectra within each window El::DistMatrix<double> invNormMap(grid); El::DistMatrix<El::Int> itCountMap(grid); const El::Int xBlock = realSize / numReal; const El::Int yBlock = imagSize / numImag; const El::Int xLeftover = realSize - (numReal-1)*xBlock; const El::Int yLeftover = imagSize - (numImag-1)*yBlock; const double realStep = realWidth/realSize; const double imagStep = imagWidth/imagSize; const El::Complex<double> corner = center - El::Complex<double>(realWidth/2,imagWidth/2); for( El::Int realChunk=0; realChunk<numReal; ++realChunk ) { const El::Int realChunkSize = ( realChunk==numReal-1 ? xLeftover : xBlock ); const double realChunkWidth = realStep*realChunkSize; for( El::Int imagChunk=0; imagChunk<numImag; ++imagChunk ) { auto chunkTag = El::BuildString("_",realChunk,"_",imagChunk); const El::Int imagChunkSize = ( imagChunk==numImag-1 ? yLeftover : yBlock ); const double imagChunkWidth = imagStep*imagChunkSize; const El::Complex<double> chunkCorner = corner + El::Complex<double> (realStep*realChunk*xBlock,imagStep*imagChunk*yBlock); const El::Complex<double> chunkCenter = chunkCorner + El::Complex<double> (realStep*realChunkSize,imagStep*imagChunkSize)/2.; if( El::mpi::Rank(comm) == 0 ) El::Output ("Starting computation for chunk centered at ",chunkCenter); El::mpi::Barrier( comm ); timer.Start(); psCtrl.snapCtrl.numBase = matName+"_"+numBase+chunkTag; psCtrl.snapCtrl.imgBase = matName+"_"+imgBase+chunkTag; if( isReal ) { itCountMap = El::QuasiTriangularSpectralWindow ( AReal, QReal, invNormMap, chunkCenter, realChunkWidth, imagChunkWidth, realChunkSize, imagChunkSize, psCtrl ); } else { itCountMap = El::TriangularSpectralWindow ( ACpx, QCpx, invNormMap, chunkCenter, realChunkWidth, imagChunkWidth, realChunkSize, imagChunkSize, psCtrl ); } El::mpi::Barrier( comm ); const double pseudoTime = timer.Stop(); const El::Int numIts = MaxNorm( itCountMap ); if( El::mpi::Rank() == 0 ) El::Output ("num seconds=",pseudoTime,"\n", "num iterations=",numIts); } } } catch( std::exception& e ) { El::ReportException(e); } return 0; }
int main( int argc, char* argv[] ) { El::Environment env( argc, argv ); try { const El::Int m = El::Input("--m","height of matrix",100); const El::Int n = El::Input("--n","width of matrix",200); const bool useIPM = El::Input("--useIPM","use Interior Point?",true); // TODO(poulson): Add options for controlling IPM const El::Int maxIter = El::Input("--maxIter","maximum # of iter's",500); const Real rho = El::Input("--rho","augmented Lagrangian param.",1.); const Real alpha = El::Input("--alpha","over-relaxation",1.2); const Real absTol = El::Input("--absTol","absolute tolerance",1e-6); const Real relTol = El::Input("--relTol","relative tolerance",1e-4); const Real pinvTol = El::Input("--pinvTol","pseudoinv tolerance",0.); const bool usePinv = El::Input("--usePinv","Directly compute pinv(A)",true); const bool progress = El::Input("--progress","print progress?",true); const bool display = El::Input("--display","display matrices?",false); const bool print = El::Input("--print","print matrices",false); El::ProcessInput(); El::PrintInputReport(); El::DistMatrix<Real> A, b, xTrue; El::Uniform( A, m, n ); El::Uniform( b, m, 1 ); if( print ) { El::Print( A, "A" ); El::Print( b, "b" ); } if( display ) El::Display( A, "A" ); const bool sparse = false; El::BPCtrl<Real> ctrl(sparse); ctrl.useIPM = useIPM; ctrl.admmCtrl.rho = rho; ctrl.admmCtrl.alpha = alpha; ctrl.admmCtrl.maxIter = maxIter; ctrl.admmCtrl.absTol = absTol; ctrl.admmCtrl.relTol = relTol; ctrl.admmCtrl.usePinv = usePinv; ctrl.admmCtrl.pinvTol = pinvTol; ctrl.admmCtrl.progress = progress; ctrl.lpIPMCtrl.mehrotraCtrl.print = true; El::DistMatrix<Real> x; El::Timer timer; if( El::mpi::Rank() == 0 ) timer.Start(); El::BP( A, b, x, ctrl ); if( El::mpi::Rank() == 0 ) timer.Stop(); if( print ) El::Print( x, "x" ); const El::Int xZeroNorm = El::ZeroNorm( x ); if( El::mpi::Rank() == 0 ) { El::Output("Basis Pursuit time: ",timer.Total()," secs"); El::Output("|| x ||_0 = ",xZeroNorm); } SoftThreshold( x, El::Sqrt(El::limits::Epsilon<Real>()) ); if( print ) El::Print( x, "xThresh" ); const El::Int xZeroNormThresh = El::ZeroNorm( x ); if( El::mpi::Rank() == 0 ) { El::Output("|| xThresh ||_0 = ",xZeroNormThresh); } } catch( std::exception& e ) { El::ReportException(e); } return 0; }