1 #ifndef SOPT_PROXIMAL_H
2 #define SOPT_PROXIMAL_H
4 #include "sopt/config.h"
21 EuclidianNorm(mpi::Communicator
const &comm = mpi::Communicator()) : comm_(comm){};
22 mpi::Communicator communicator()
const {
return comm_; }
28 template <
typename T0>
31 Eigen::MatrixBase<T0>
const &x)
const {
36 auto const norm = x.norm();
39 out = (
Scalar(1) - t / norm) * x;
44 template <
typename T0>
46 Eigen::MatrixBase<T0>
const &x)
const {
51 mpi::Communicator comm_;
56 template <
typename T0>
58 Eigen::MatrixBase<T0>
const &x) -> decltype(
EuclidianNorm(), t, x) {
63 template <
typename T0,
typename T1>
65 Eigen::DenseBase<T1>
const &x) {
66 out = sopt::soft_threshhold<T0>(x, gamma);
69 template <
typename T0,
typename T1,
typename T2>
70 void l1_norm(Eigen::DenseBase<T0> &out, Eigen::DenseBase<T2>
const &gamma,
71 Eigen::DenseBase<T1>
const &x) {
72 out = sopt::soft_threshhold<T0, T2>(x, gamma);
79 l1_norm<Vector<S>,
Vector<S>>(out, gamma, x);
83 template <
typename T0,
typename T1>
85 Eigen::DenseBase<T1>
const &x) {
86 out = x.derived() * 1. / (1. + gamma);
89 template <
typename T0,
typename T1,
typename T2>
90 void l2_norm(Eigen::DenseBase<T0> &out, Eigen::DenseBase<T2>
const &gamma,
91 Eigen::DenseBase<T1>
const &x) {
92 out = x.derived().array() * 1. / (1. + gamma.derived().array()).array();
96 template <
typename T0,
typename T1>
98 Eigen::DenseBase<T1>
const &x) {
99 typename Eigen::Index
const size = x.size() / 2;
100 typename T1::PlainObject
const &u = x.segment(0, size);
101 typename T1::PlainObject
const &v = x.segment(size, size);
102 out = T0::Zero(size * 2);
103 for (
typename Eigen::Index i(0); i < size; i++) {
104 const t_real norm = std::sqrt(std::abs(u(i) * u(i) + v(i) * v(i)));
106 out(i) = (1 - gamma / norm) * u(i);
107 out(size + i) = (1 - gamma / norm) * v(i);
114 template <
typename T0,
typename T1,
typename T2>
115 void tv_norm(Eigen::DenseBase<T0> &out, Eigen::DenseBase<T2>
const &gamma,
116 Eigen::DenseBase<T1>
const &x) {
117 typename Eigen::Index
const size = x.size() / 2;
118 typename T1::PlainObject
const &u = x.segment(0, size);
119 typename T1::PlainObject
const &v = x.segment(size, size);
120 out = T0::Zero(size * 2);
121 for (
typename Eigen::Index i(0); i < size; i++) {
122 const t_real norm = std::sqrt(std::abs(u(i) * u(i) + v(i) * v(i)));
123 if (norm > gamma(i)) {
124 out(i) = (1 - gamma(i) / norm) * u(i);
125 out(size + i) = (1 - gamma(i) / norm) * v(i);
134 template <
typename T0,
typename T1>
136 Eigen::DenseBase<T1>
const &x) {
143 template <
typename T>
150 template <
typename T>
156 template <
typename T>
168 template <
typename T0>
174 template <
typename T0>
181 template <
typename T>
188 : epsilon_(
epsilon), comm_(comm){};
202 auto const norm = x.stableNorm();
210 template <
typename T0>
216 template <
typename T0>
230 mpi::Communicator
const &communicator()
const {
return comm_; }
231 L2Ball &communicator(mpi::Communicator
const &comm) {
241 mpi::Communicator comm_;
245 template <
typename T>
252 template <
typename T0>
254 mpi::Communicator
const &comm = mpi::Communicator())
259 mpi::Communicator communicator()
const {
return L2Ball<T>::communicator(); }
260 WeightedL2Ball<T> &communicator(mpi::Communicator
const &c) {
261 L2Ball<T>::communicator(c);
266 template <
typename T0>
281 auto const norm =
weights().size() == 1 ? x.stableNorm() * std::abs(
weights()(0))
282 : (x.array() *
weights().array()).matrix().stableNorm();
290 template <
typename T0>
292 Eigen::MatrixBase<T0>
const &x)
const {
296 template <
typename T0>
304 template <
typename T0>
306 if ((w.array() < 0e0).any())
SOPT_THROW(
"Weights cannot be negative");
307 if (w.stableNorm() < 1e-12)
SOPT_THROW(
"Weights cannot be null");
324 template <
typename FUNCTION,
typename VECTOR>
328 template <
typename T_VECTOR>
329 Translation(FUNCTION
const &func, T_VECTOR
const &trans) : func(func), trans(trans) {}
331 template <
typename OUTPUT,
typename T0>
332 typename std::enable_if<std::is_reference<OUTPUT>::value,
void>::type
operator()(
334 Eigen::MatrixBase<T0>
const &x)
const {
335 func(out, t, x + trans);
339 template <
typename T0>
342 Eigen::MatrixBase<T0>
const &x)
const {
343 func(out, t, x + trans);
347 template <
typename T0>
349 typename T0::Scalar const &t, Eigen::MatrixBase<T0>
const &x)
const {
350 return {*
this, t, x};
361 template <
typename FUNCTION,
typename VECTOR>
sopt::Vector< Scalar > t_Vector
Computes inner-most element type.
Proximal of euclidian norm.
void operator()(Vector< typename T0::Scalar > &out, typename real_type< typename T0::Scalar >::type const &t, Eigen::MatrixBase< T0 > const &x) const
ProximalExpression< EuclidianNorm, T0 > operator()(typename T0::Scalar const &t, Eigen::MatrixBase< T0 > const &x) const
Lazy version.
Proximal for indicator function of L2 ball.
Real epsilon() const
Size of the ball.
void operator()(Vector< T > &out, typename real_type< T >::type, Vector< T > const &x) const
Calls proximal function.
L2Ball(Real epsilon)
Constructs an L2 ball proximal of size epsilon.
EnveloppeExpression< L2Ball, T0 > operator()(Real const &, Eigen::MatrixBase< T0 > const &x) const
Lazy version.
L2Ball< T > & epsilon(Real eps)
Size of the ball.
typename real_type< T >::type Real
EnveloppeExpression< L2Ball, T0 > operator()(Eigen::MatrixBase< T0 > const &x) const
Lazy version.
void operator()(Vector< T > &out, Vector< T > const &x) const
Calls proximal function.
Proximal for the L2 norm.
EnveloppeExpression< L2Norm, T0 > operator()(Real const &, Eigen::MatrixBase< T0 > const &x) const
Lazy version.
void operator()(Vector< T > &out, const Real gamma, Vector< T > const &x) const
Calls proximal function.
typename real_type< T >::type Real
EnveloppeExpression< L2Norm, T0 > operator()(Eigen::MatrixBase< T0 > const &x) const
Lazy version.
L2Norm()
Constructs an L2 ball proximal of size gamma.
Translation over proximal function.
std::enable_if< std::is_reference< OUTPUT >::value, void >::type operator()(OUTPUT out, typename real_type< typename T0::Scalar >::type const &t, Eigen::MatrixBase< T0 > const &x) const
Computes proximal of translated function.
Translation(FUNCTION const &func, T_VECTOR const &trans)
Creates proximal of translated function.
ProximalExpression< Translation< FUNCTION, VECTOR > const &, T0 > operator()(typename T0::Scalar const &t, Eigen::MatrixBase< T0 > const &x) const
Lazy version.
void operator()(Vector< typename T0::Scalar > &out, typename real_type< typename T0::Scalar >::type const &t, Eigen::MatrixBase< T0 > const &x) const
Computes proximal of translated function.
WeightedL2Ball< T > & weights(Eigen::MatrixBase< T0 > const &w)
Weights associated with each dimension.
void operator()(Vector< T > &out, typename real_type< T >::type, Vector< T > const &x) const
Calls proximal function.
t_Vector const & weights() const
Weights associated with each dimension.
EnveloppeExpression< WeightedL2Ball, T0 > operator()(Eigen::MatrixBase< T0 > const &x) const
Lazy version.
WeightedL2Ball(Real epsilon, Eigen::DenseBase< T0 > const &w)
Constructs an L2 ball proximal of size epsilon with given weights.
WeightedL2Ball(Real epsilon)
Constructs an L2 ball proximal of size epsilon.
void operator()(Vector< T > &out, Vector< T > const &x) const
Calls proximal function.
WeightedL2Ball< T > & epsilon(Real const &eps)
Size of the ball.
EnveloppeExpression< WeightedL2Ball, T0 > operator()(Real const &, Eigen::MatrixBase< T0 > const &x) const
Lazy version.
Real epsilon() const
Size of the ball.
typename L2Ball< T >::Real Real
Expression referencing a lazy function call to envelope proximal.
Expression referencing a lazy proximal function call.
Holds some standard proximals.
void l2_norm(Eigen::DenseBase< T0 > &out, typename real_type< typename T0::Scalar >::type gamma, Eigen::DenseBase< T1 > const &x)
Proximal of the l2 norm (note this is different from the l2 ball indicator function)
Translation< FUNCTION, VECTOR > translate(FUNCTION const &func, VECTOR const &translation)
Translates given proximal by given vector.
void id(Eigen::DenseBase< T0 > &out, typename real_type< typename T0::Scalar >::type gamma, Eigen::DenseBase< T1 > const &x)
Proximal of a function that is always zero, the identity.
void positive_quadrant(Vector< T > &out, typename real_type< T >::type, Vector< T > const &x)
Proximal for projection on the positive quadrant.
void tv_norm(Eigen::DenseBase< T0 > &out, typename real_type< typename T0::Scalar >::type gamma, Eigen::DenseBase< T1 > const &x)
Proximal of the l1,2 norm that is used in the TV norm.
auto euclidian_norm(typename real_type< typename T0::Scalar >::type const &t, Eigen::MatrixBase< T0 > const &x) -> decltype(EuclidianNorm(), t, x)
Proximal of the euclidian norm.
void l1_norm(Eigen::DenseBase< T0 > &out, typename real_type< typename T0::Scalar >::type gamma, Eigen::DenseBase< T1 > const &x)
Proximal of the l1 norm.
void l2_norm(Eigen::DenseBase< T0 > &out, Eigen::DenseBase< T2 > const &gamma, Eigen::DenseBase< T1 > const &x)
Eigen::CwiseUnaryOp< const details::ProjectPositiveQuadrant< typename T::Scalar >, const T > positive_quadrant(Eigen::DenseBase< T > const &input)
Expression to create projection onto positive quadrant.
std::enable_if< std::is_arithmetic< SCALAR >::value or is_complex< SCALAR >::value, SCALAR >::type soft_threshhold(SCALAR const &x, typename real_type< SCALAR >::type const &threshhold)
abs(x) < threshhold ? 0: x - sgn(x) * threshhold
double t_real
Root of the type hierarchy for real numbers.
Eigen::Matrix< T, Eigen::Dynamic, 1 > Vector
A vector of a given type.