void XnVPointDenoiser::UpdatePointDenoise(XnPoint3D &ptToChange, const XnPoint3D &ptDontChange) { XnV3DVector vDir = XnV3DVector(ptDontChange) - XnV3DVector(ptToChange); XnFloat fLen = vDir.Normalize(); XnFloat fSoftThreshold = SoftThreshold(fLen, m_fDistanceThreshold); XnV3DVector vToChange = ptToChange; XnV3DVector vDontChange = ptDontChange; if (fSoftThreshold == 0) { ptToChange = vToChange*(1-m_fCloseRatio) + vDontChange*m_fCloseRatio; } else { XnV3DVector vNewPoint = XnV3DVector(ptToChange) + (fSoftThreshold) * vDir; ptToChange = vToChange*(1-m_fFarRatio) + vNewPoint*m_fFarRatio; } } // XnVPointDenoiser::UpdatePointDenoise
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; }
inline void ADMM ( const Matrix<F>& M, Matrix<F>& L, Matrix<F>& S, const RPCACtrl<Base<F>>& ctrl ) { typedef Base<F> Real; const Int m = M.Height(); const Int n = M.Width(); // If tau is not specified, then set it to 1/sqrt(max(m,n)) const Base<F> tau = ( ctrl.tau <= Real(0) ? Real(1)/sqrt(Real(Max(m,n))) : ctrl.tau ); if( ctrl.beta <= Real(0) ) LogicError("beta cannot be non-positive"); if( ctrl.tol <= Real(0) ) LogicError("tol cannot be non-positive"); const Base<F> beta = ctrl.beta; const Base<F> tol = ctrl.tol; const double startTime = mpi::Time(); Matrix<F> E, Y; Zeros( Y, m, n ); const Real frobM = FrobeniusNorm( M ); const Real maxM = MaxNorm( M ); if( ctrl.progress ) cout << "|| M ||_F = " << frobM << "\n" << "|| M ||_max = " << maxM << endl; Zeros( L, m, n ); Zeros( S, m, n ); Int numIts = 0; while( true ) { ++numIts; // ST_{tau/beta}(M - L + Y/beta) S = M; S -= L; Axpy( F(1)/beta, Y, S ); SoftThreshold( S, tau/beta ); const Int numNonzeros = ZeroNorm( S ); // SVT_{1/beta}(M - S + Y/beta) L = M; L -= S; Axpy( F(1)/beta, Y, L ); Int rank; if( ctrl.usePivQR ) rank = SVT( L, Real(1)/beta, ctrl.numPivSteps ); else rank = SVT( L, Real(1)/beta ); // E := M - (L + S) E = M; E -= L; E -= S; const Real frobE = FrobeniusNorm( E ); if( frobE/frobM <= tol ) { if( ctrl.progress ) cout << "Converged after " << numIts << " iterations " << " with rank=" << rank << ", numNonzeros=" << numNonzeros << " and " << "|| E ||_F / || M ||_F = " << frobE/frobM << ", and " << mpi::Time()-startTime << " total secs" << endl; break; } else if( numIts >= ctrl.maxIts ) { if( ctrl.progress ) cout << "Aborting after " << numIts << " iterations and " << mpi::Time()-startTime << " total secs" << endl; break; } else { if( ctrl.progress ) cout << numIts << ": || E ||_F / || M ||_F = " << frobE/frobM << ", rank=" << rank << ", numNonzeros=" << numNonzeros << ", " << mpi::Time()-startTime << " total secs" << endl; } // Y := Y + beta E Axpy( beta, E, Y ); } }
inline void ALM ( const ElementalMatrix<F>& MPre, ElementalMatrix<F>& LPre, ElementalMatrix<F>& SPre, const RPCACtrl<Base<F>>& ctrl ) { DistMatrixReadProxy<F,F,MC,MR> MProx( MPre ); DistMatrixWriteProxy<F,F,MC,MR> LProx( LPre ), SProx( SPre ); auto& M = MProx.GetLocked(); auto& L = LProx.Get(); auto& S = SProx.Get(); typedef Base<F> Real; const Int m = M.Height(); const Int n = M.Width(); const int commRank = mpi::Rank( M.Grid().Comm() ); // If tau is unspecified, set it to 1/sqrt(max(m,n)) const Base<F> tau = ( ctrl.tau <= Real(0) ? Real(1) / sqrt(Real(Max(m,n))) : ctrl.tau ); if( ctrl.tol <= Real(0) ) LogicError("tol cannot be non-positive"); const Base<F> tol = ctrl.tol; const double startTime = mpi::Time(); DistMatrix<F> Y( M ); NormalizeEntries( Y ); const Real twoNorm = TwoNorm( Y ); const Real maxNorm = MaxNorm( Y ); const Real infNorm = maxNorm / tau; const Real dualNorm = Max( twoNorm, infNorm ); Y *= F(1)/dualNorm; // If beta is unspecified, set it to 1 / 2 || sign(M) ||_2 Base<F> beta = ( ctrl.beta <= Real(0) ? Real(1) / (2*twoNorm) : ctrl.beta ); const Real frobM = FrobeniusNorm( M ); const Real maxM = MaxNorm( M ); if( ctrl.progress && commRank == 0 ) cout << "|| M ||_F = " << frobM << "\n" << "|| M ||_max = " << maxM << endl; Zeros( L, m, n ); Zeros( S, m, n ); Int numIts=0, numPrimalIts=0; DistMatrix<F> LLast( M.Grid() ), SLast( M.Grid() ), E( M.Grid() ); while( true ) { ++numIts; Int rank, numNonzeros; while( true ) { ++numPrimalIts; LLast = L; SLast = S; // ST_{tau/beta}(M - L + Y/beta) S = M; S -= L; Axpy( F(1)/beta, Y, S ); SoftThreshold( S, tau/beta ); numNonzeros = ZeroNorm( S ); // SVT_{1/beta}(M - S + Y/beta) L = M; L -= S; Axpy( F(1)/beta, Y, L ); if( ctrl.usePivQR ) rank = SVT( L, Real(1)/beta, ctrl.numPivSteps ); else rank = SVT( L, Real(1)/beta ); LLast -= L; SLast -= S; const Real frobLDiff = FrobeniusNorm( LLast ); const Real frobSDiff = FrobeniusNorm( SLast ); if( frobLDiff/frobM < tol && frobSDiff/frobM < tol ) { if( ctrl.progress && commRank == 0 ) cout << "Primal loop converged: " << mpi::Time()-startTime << " total secs" << endl; break; } else { if( ctrl.progress && commRank == 0 ) cout << " " << numPrimalIts << ": \n" << " || Delta L ||_F / || M ||_F = " << frobLDiff/frobM << "\n" << " || Delta S ||_F / || M ||_F = " << frobSDiff/frobM << "\n" << " rank=" << rank << ", numNonzeros=" << numNonzeros << ", " << mpi::Time()-startTime << " total secs" << endl; } } // E := M - (L + S) E = M; E -= L; E -= S; const Real frobE = FrobeniusNorm( E ); if( frobE/frobM <= tol ) { if( ctrl.progress && commRank == 0 ) cout << "Converged after " << numIts << " iterations and " << numPrimalIts << " primal iterations with rank=" << rank << ", numNonzeros=" << numNonzeros << " and " << "|| E ||_F / || M ||_F = " << frobE/frobM << ", " << mpi::Time()-startTime << " total secs" << endl; break; } else if( numIts >= ctrl.maxIts ) { if( ctrl.progress && commRank == 0 ) cout << "Aborting after " << numIts << " iterations and " << mpi::Time()-startTime << " total secs" << endl; break; } else { if( ctrl.progress && commRank == 0 ) cout << numPrimalIts << ": || E ||_F / || M ||_F = " << frobE/frobM << ", rank=" << rank << ", numNonzeros=" << numNonzeros << ", " << mpi::Time()-startTime << " total secs" << endl; } // Y := Y + beta E Axpy( beta, E, Y ); beta *= ctrl.rho; } }
inline void ADMM ( const AbstractDistMatrix<F>& MPre, AbstractDistMatrix<F>& LPre, AbstractDistMatrix<F>& SPre, const RPCACtrl<Base<F>>& ctrl ) { auto MPtr = ReadProxy<F,MC,MR>( &MPre ); auto& M = *MPtr; auto LPtr = WriteProxy<F,MC,MR>( &LPre ); auto& L = *LPtr; auto SPtr = WriteProxy<F,MC,MR>( &SPre ); auto& S = *SPtr; typedef Base<F> Real; const Int m = M.Height(); const Int n = M.Width(); const Int commRank = mpi::Rank( M.Grid().Comm() ); // If tau is not specified, then set it to 1/sqrt(max(m,n)) const Base<F> tau = ( ctrl.tau <= Real(0) ? Real(1)/sqrt(Real(Max(m,n))) : ctrl.tau ); if( ctrl.beta <= Real(0) ) LogicError("beta cannot be non-positive"); if( ctrl.tol <= Real(0) ) LogicError("tol cannot be non-positive"); const Base<F> beta = ctrl.beta; const Base<F> tol = ctrl.tol; const double startTime = mpi::Time(); DistMatrix<F> E( M.Grid() ), Y( M.Grid() ); Zeros( Y, m, n ); const Real frobM = FrobeniusNorm( M ); const Real maxM = MaxNorm( M ); if( ctrl.progress && commRank == 0 ) cout << "|| M ||_F = " << frobM << "\n" << "|| M ||_max = " << maxM << endl; Zeros( L, m, n ); Zeros( S, m, n ); Int numIts = 0; while( true ) { ++numIts; // ST_{tau/beta}(M - L + Y/beta) S = M; Axpy( F(-1), L, S ); Axpy( F(1)/beta, Y, S ); SoftThreshold( S, tau/beta ); const Int numNonzeros = ZeroNorm( S ); // SVT_{1/beta}(M - S + Y/beta) L = M; Axpy( F(-1), S, L ); Axpy( F(1)/beta, Y, L ); Int rank; if( ctrl.usePivQR ) rank = SVT( L, Real(1)/beta, ctrl.numPivSteps ); else rank = SVT( L, Real(1)/beta ); // E := M - (L + S) E = M; Axpy( F(-1), L, E ); Axpy( F(-1), S, E ); const Real frobE = FrobeniusNorm( E ); if( frobE/frobM <= tol ) { if( ctrl.progress && commRank == 0 ) cout << "Converged after " << numIts << " iterations " << " with rank=" << rank << ", numNonzeros=" << numNonzeros << " and " << "|| E ||_F / || M ||_F = " << frobE/frobM << ", and " << mpi::Time()-startTime << " total secs" << endl; break; } else if( numIts >= ctrl.maxIts ) { if( ctrl.progress && commRank == 0 ) cout << "Aborting after " << numIts << " iterations and " << mpi::Time()-startTime << " total secs" << endl; break; } else { if( ctrl.progress && commRank == 0 ) cout << numIts << ": || E ||_F / || M ||_F = " << frobE/frobM << ", rank=" << rank << ", numNonzeros=" << numNonzeros << ", " << mpi::Time()-startTime << " total secs" << endl; } // Y := Y + beta E Axpy( beta, E, Y ); } }
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; }