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 Mehrotra ( const DistSparseMatrix<Real>& A, const DistMultiVec<Real>& b, const DistMultiVec<Real>& c, const DistMultiVec<Int>& orders, const DistMultiVec<Int>& firstInds, DistMultiVec<Real>& x, DistMultiVec<Real>& y, DistMultiVec<Real>& z, const MehrotraCtrl<Real>& ctrl ) { EL_DEBUG_CSE const Int n = c.Height(); const Grid& grid = A.Grid(); DistSparseMatrix<Real> G(grid); Identity( G, n, n ); G *= -1; DistMultiVec<Real> h(grid); Zeros( h, n, 1 ); MehrotraCtrl<Real> affineCtrl = ctrl; affineCtrl.primalInit = false; affineCtrl.dualInit = false; DistMultiVec<Real> s(grid); socp::affine::Mehrotra(A,G,b,c,h,orders,firstInds,x,y,z,s,affineCtrl); }
void LAV ( const DistSparseMatrix<Real>& A, const DistMultiVec<Real>& b, DistMultiVec<Real>& x, const lp::affine::Ctrl<Real>& ctrl ) { EL_DEBUG_CSE const Int m = A.Height(); const Int n = A.Width(); const Grid& grid = A.Grid(); DistSparseMatrix<Real> AHat(grid), G(grid); DistMultiVec<Real> c(grid), h(grid); // c := [0;1;1] // ============ Zeros( c, n+2*m, 1 ); for( Int iLoc=0; iLoc<c.LocalHeight(); ++iLoc ) if( c.GlobalRow(iLoc) >= n ) c.SetLocal( iLoc, 0, Real(1) ); // \hat A := [A, I, -I] // ==================== Zeros( AHat, m, n+2*m ); const Int numLocalEntriesA = A.NumLocalEntries(); AHat.Reserve( numLocalEntriesA + 2*AHat.LocalHeight() ); for( Int e=0; e<numLocalEntriesA; ++e ) AHat.QueueUpdate( A.Row(e), A.Col(e), A.Value(e) ); for( Int iLoc=0; iLoc<AHat.LocalHeight(); ++iLoc ) { const Int i = AHat.GlobalRow(iLoc); AHat.QueueLocalUpdate( iLoc, i+n, Real( 1) ); AHat.QueueLocalUpdate( iLoc, i+n+m, Real(-1) ); } AHat.ProcessLocalQueues(); // G := | 0 -I 0 | // | 0 0 -I | // ================ Zeros( G, 2*m, n+2*m ); G.Reserve( G.LocalHeight() ); for( Int iLoc=0; iLoc<G.LocalHeight(); ++iLoc ) G.QueueLocalUpdate( iLoc, G.GlobalRow(iLoc)+n, Real(-1) ); G.ProcessLocalQueues(); // h := | 0 | // | 0 | // ========== Zeros( h, 2*m, 1 ); // Solve the affine QP // =================== DistMultiVec<Real> xHat(grid), y(grid), z(grid), s(grid); LP( AHat, G, b, c, h, xHat, y, z, s, ctrl ); // Extract x // ========= x = xHat( IR(0,n), ALL ); }
DistSparseMatrix<Ring>::DistSparseMatrix( const DistSparseMatrix<Ring>& A ) { EL_DEBUG_CSE distGraph_.numSources_ = -1; distGraph_.numTargets_ = -1; distGraph_.grid_ = &A.Grid(); if( &A != this ) *this = A; EL_DEBUG_ONLY( else LogicError("Tried to construct DistMultiVec via itself"); ) }
void KKT ( const DistSparseMatrix<Real>& A, const DistSparseMatrix<Real>& G, const DistMultiVec<Real>& s, const DistMultiVec<Real>& z, DistSparseMatrix<Real>& J, bool onlyLower ) { EL_DEBUG_CSE const Int n = A.Width(); DistSparseMatrix<Real> Q(A.Grid()); Q.Resize( n, n ); qp::affine::KKT( Q, A, G, s, z, J, onlyLower ); }
void StaticKKT ( const DistSparseMatrix<Real>& A, const DistSparseMatrix<Real>& G, Real gamma, Real delta, Real beta, DistSparseMatrix<Real>& J, bool onlyLower ) { EL_DEBUG_CSE const Int n = A.Width(); DistSparseMatrix<Real> Q(A.Grid()); Q.Resize( n, n ); qp::affine::StaticKKT( Q, A, G, gamma, delta, beta, J, onlyLower ); }
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); } }
void EN ( const DistSparseMatrix<Real>& A, const DistMultiVec<Real>& b, Real lambda1, Real lambda2, DistMultiVec<Real>& x, const qp::affine::Ctrl<Real>& ctrl ) { EL_DEBUG_CSE const Int m = A.Height(); const Int n = A.Width(); const Grid& grid = A.Grid(); DistSparseMatrix<Real> Q(grid), AHat(grid), G(grid); DistMultiVec<Real> c(grid), h(grid); // Q := | 2*lambda_2 0 0 | // | 0 2*lambda_2 0 | // | 0 0 2 | // ================================ Zeros( Q, 2*n+m, 2*n+m ); Q.Reserve( Q.LocalHeight() ); for( Int iLoc=0; iLoc<Q.LocalHeight(); ++iLoc ) { const Int i = Q.GlobalRow(iLoc); if( i < 2*n ) Q.QueueLocalUpdate( iLoc, i, 2*lambda2 ); else Q.QueueLocalUpdate( iLoc, i, Real(2) ); } Q.ProcessLocalQueues(); // c := lambda_1*[1;1;0] // ===================== Zeros( c, 2*n+m, 1 ); for( Int iLoc=0; iLoc<c.LocalHeight(); ++iLoc ) if( c.GlobalRow(iLoc) < 2*n ) c.SetLocal( iLoc, 0, lambda1 ); // \hat A := [A, -A, I] // ==================== // NOTE: Since A and \hat A are the same height and each distributed within // columns, it is possible to form \hat A from A without communication const Int numLocalEntriesA = A.NumLocalEntries(); Zeros( AHat, m, 2*n+m ); AHat.Reserve( 2*numLocalEntriesA+AHat.LocalHeight() ); for( Int e=0; e<numLocalEntriesA; ++e ) { AHat.QueueUpdate( A.Row(e), A.Col(e), A.Value(e) ); AHat.QueueUpdate( A.Row(e), A.Col(e)+n, -A.Value(e) ); } for( Int iLoc=0; iLoc<AHat.LocalHeight(); ++iLoc ) { const Int i = AHat.GlobalRow(iLoc); AHat.QueueLocalUpdate( iLoc, i+2*n, Real(1) ); } AHat.ProcessLocalQueues(); // G := | -I 0 0 | // | 0 -I 0 | // ================ Zeros( G, 2*n, 2*n+m ); G.Reserve( G.LocalHeight() ); for( Int iLoc=0; iLoc<G.LocalHeight(); ++iLoc ) { const Int i = G.GlobalRow(iLoc); G.QueueLocalUpdate( iLoc, i, Real(-1) ); } G.ProcessLocalQueues(); // h := 0 // ====== Zeros( h, 2*n, 1 ); // Solve the affine QP // =================== DistMultiVec<Real> xHat(grid), y(grid), z(grid), s(grid); QP( Q, AHat, G, b, c, h, xHat, y, z, s, ctrl ); // x := u - v // ========== Zeros( x, n, 1 ); Int numRemoteUpdates = 0; for( Int iLoc=0; iLoc<xHat.LocalHeight(); ++iLoc ) if( xHat.GlobalRow(iLoc) < 2*n ) ++numRemoteUpdates; else break; x.Reserve( numRemoteUpdates ); for( Int iLoc=0; iLoc<xHat.LocalHeight(); ++iLoc ) { const Int i = xHat.GlobalRow(iLoc); if( i < n ) x.QueueUpdate( i, 0, xHat.GetLocal(iLoc,0) ); else if( i < 2*n ) x.QueueUpdate( i-n, 0, -xHat.GetLocal(iLoc,0) ); else break; } x.ProcessQueues(); }