void PushPairInto ( DistMultiVec<Real>& s, DistMultiVec<Real>& z, const DistMultiVec<Real>& w, const DistMultiVec<Int>& orders, const DistMultiVec<Int>& firstInds, Real wMaxNormLimit, Int cutoff ) { DEBUG_ONLY(CSE cse("soc::PushPairInto")) DistMultiVec<Real> sLower(s.Comm()), zLower(z.Comm()); soc::LowerNorms( s, sLower, orders, firstInds, cutoff ); soc::LowerNorms( z, zLower, orders, firstInds, cutoff ); const int localHeight = s.LocalHeight(); for( Int iLoc=0; iLoc<localHeight; ++iLoc ) { const Int i = s.GlobalRow(iLoc); const Real w0 = w.GetLocal(iLoc,0); if( i == firstInds.GetLocal(iLoc,0) && w0 > wMaxNormLimit ) { // TODO: Switch to a non-adhoc modification s.UpdateLocal( iLoc, 0, Real(1)/wMaxNormLimit ); z.UpdateLocal( iLoc, 0, Real(1)/wMaxNormLimit ); } } }
void SOCSquareRoot ( const DistMultiVec<Real>& x, DistMultiVec<Real>& xRoot, const DistMultiVec<Int>& orders, const DistMultiVec<Int>& firstInds, Int cutoff ) { DEBUG_ONLY(CSE cse("SOCSquareRoot")) DistMultiVec<Real> d(x.Comm()); SOCDets( x, d, orders, firstInds ); ConeBroadcast( d, orders, firstInds ); auto roots = x; ConeBroadcast( roots, orders, firstInds ); const Int localHeight = x.LocalHeight(); xRoot.SetComm( x.Comm() ); Zeros( xRoot, x.Height(), 1 ); for( Int iLoc=0; iLoc<localHeight; ++iLoc ) { const Int i = x.GlobalRow(iLoc); const Real x0 = roots.GetLocal(iLoc,0); const Real det = d.GetLocal(iLoc,0); const Real eta0 = Sqrt(x0+Sqrt(det))/Sqrt(Real(2)); if( i == firstInds.GetLocal(iLoc,0) ) xRoot.SetLocal( iLoc, 0, eta0 ); else xRoot.SetLocal( iLoc, 0, x.GetLocal(iLoc,0)/(2*eta0) ); } }
void RowMaxNorms( const DistMultiVec<F>& A, DistMultiVec<Base<F>>& norms ) { DEBUG_CSE norms.SetComm( A.Comm() ); norms.Resize( A.Height(), 1 ); RowMaxNorms( A.LockedMatrix(), norms.Matrix() ); }
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(); mpi::Comm comm = c.Comm(); DistSparseMatrix<Real> G(comm); Identity( G, n, n ); G *= -1; DistMultiVec<Real> h(comm); Zeros( h, n, 1 ); MehrotraCtrl<Real> affineCtrl = ctrl; affineCtrl.primalInit = false; affineCtrl.dualInit = false; DistMultiVec<Real> s(comm); socp::affine::Mehrotra(A,G,b,c,h,orders,firstInds,x,y,z,s,affineCtrl); }
void EntrywiseMap ( const DistMultiVec<S>& A, DistMultiVec<T>& B, function<T(S)> func ) { DEBUG_CSE B.SetComm( A.Comm() ); B.Resize( A.Height(), A.Width() ); EntrywiseMap( A.LockedMatrix(), B.Matrix(), func ); }
void SOCApply ( const DistMultiVec<Real>& x, DistMultiVec<Real>& y, const DistMultiVec<Int>& orders, const DistMultiVec<Int>& firstInds, Int cutoff ) { DEBUG_ONLY(CSE cse("SOCApply")) // TODO?: Optimize DistMultiVec<Real> z(x.Comm()); SOCApply( x, y, z, orders, firstInds, cutoff ); y = z; }
Real ComplementRatio ( const DistMultiVec<Real>& s, const DistMultiVec<Real>& z ) { DEBUG_CSE const Int localHeight = s.LocalHeight(); const Real* sBuf = s.LockedMatrix().LockedBuffer(); const Real* zBuf = z.LockedMatrix().LockedBuffer(); Real maxLocProd = 0; for( Int iLoc=0; iLoc<localHeight; ++iLoc ) maxLocProd = Max( sBuf[iLoc]*zBuf[iLoc], maxLocProd ); const Real maxProd = mpi::AllReduce( maxLocProd, mpi::MAX, s.Comm() ); Real minLocProd = maxProd; for( Int iLoc=0; iLoc<localHeight; ++iLoc ) minLocProd = Min( sBuf[iLoc]*zBuf[iLoc], minLocProd ); const Real minProd = mpi::AllReduce( minLocProd, mpi::MIN, s.Comm() ); return maxProd/minProd; }
Int Degree( const DistMultiVec<Int>& firstInds ) { DEBUG_CSE Int localDegree = 0; const Int localHeight = firstInds.LocalHeight(); auto& firstIndsLoc = firstInds.LockedMatrix(); for( Int iLoc=0; iLoc<localHeight; ++iLoc ) { const Int i = firstInds.GlobalRow(iLoc); if( i == firstIndsLoc(iLoc) ) ++localDegree; } return mpi::AllReduce( localDegree, firstInds.Comm() ); }
Int NumOutside( const DistMultiVec<Real>& A ) { EL_DEBUG_CSE const Int localHeight = A.LocalHeight(); const Int width = A.Width(); const Real* ABuf = A.LockedMatrix().LockedBuffer(); const Int ALDim = A.LockedMatrix().LDim(); Int numLocalNonPos = 0; for( Int iLoc=0; iLoc<localHeight; ++iLoc ) for( Int j=0; j<width; ++j ) if( ABuf[iLoc+j*ALDim] <= Real(0) ) ++numLocalNonPos; return mpi::AllReduce( numLocalNonPos, A.Comm() ); }
void NesterovTodd ( const DistMultiVec<Real>& s, const DistMultiVec<Real>& z, DistMultiVec<Real>& w ) { DEBUG_CSE w.SetComm( s.Comm() ); w.Resize( s.Height(), 1 ); const Real* sBuf = s.LockedMatrix().LockedBuffer(); const Real* zBuf = z.LockedMatrix().LockedBuffer(); Real* wBuf = w.Matrix().Buffer(); const Int localHeight = w.LocalHeight(); for( Int iLoc=0; iLoc<localHeight; ++iLoc ) wBuf[iLoc] = Sqrt(sBuf[iLoc]/zBuf[iLoc]); }
Real MaxStep ( const DistMultiVec<Real>& s, const DistMultiVec<Real>& ds, Real upperBound ) { EL_DEBUG_CSE const Int kLocal = s.LocalHeight(); const Real* sBuf = s.LockedMatrix().LockedBuffer(); const Real* dsBuf = ds.LockedMatrix().LockedBuffer(); Real alpha = upperBound; for( Int iLoc=0; iLoc<kLocal; ++iLoc ) { const Real si = sBuf[iLoc]; const Real dsi = dsBuf[iLoc]; if( dsi < Real(0) ) alpha = Min(alpha,-si/dsi); } return mpi::AllReduce( alpha, mpi::MIN, s.Comm() ); }
void Inverse ( const DistMultiVec<Real>& x, DistMultiVec<Real>& xInv, const DistMultiVec<Int>& orders, const DistMultiVec<Int>& firstInds, Int cutoff ) { DEBUG_CSE DistMultiVec<Real> dInv(x.Comm()); soc::Dets( x, dInv, orders, firstInds, cutoff ); cone::Broadcast( dInv, orders, firstInds ); auto entryInv = [=]( Real alpha ) { return Real(1)/alpha; }; EntrywiseMap( dInv, function<Real(Real)>(entryInv) ); auto Rx = x; soc::Reflect( Rx, orders, firstInds ); Hadamard( dInv, Rx, xInv ); }
void PushInto ( DistMultiVec<Real>& x, const DistMultiVec<Int>& orders, const DistMultiVec<Int>& firstInds, Real minDist, Int cutoff ) { DEBUG_ONLY(CSE cse("soc::PushInto")) DistMultiVec<Real> d(x.Comm()); soc::LowerNorms( x, d, orders, firstInds, cutoff ); const int localHeight = x.LocalHeight(); for( Int iLoc=0; iLoc<localHeight; ++iLoc ) { const Int i = x.GlobalRow(iLoc); const Real x0 = x.GetLocal(iLoc,0); const Real lowerNorm = d.GetLocal(iLoc,0); if( i == firstInds.GetLocal(iLoc,0) && x0-lowerNorm < minDist ) x.UpdateLocal( iLoc, 0, minDist - (x0-lowerNorm) ); } }