SOPT
Sparse OPTimisation
Functions
euclidian_norm.cc File Reference
#include <exception>
#include "sopt/sdmm.h"
#include "sopt/types.h"
+ Include dependency graph for euclidian_norm.cc:

Go to the source code of this file.

Functions

int main (int, char const **)
 

Function Documentation

◆ main()

int main ( int  ,
char const **   
)

Definition at line 6 of file euclidian_norm.cc.

6  {
7 
8  // Some type aliases for simplicity
9  using t_Scalar = sopt::t_complex;
12 
13  // Creates the transformation matrices
14  auto constexpr N = 10;
15  t_Matrix const L0 = t_Matrix::Random(N, N) * 2;
16  t_Matrix const L1 = t_Matrix::Random(N, N) * 4;
17  // L1_direct and L1_adjoint are used to demonstrate that we can define L_i in SDMM both directly
18  // as matrices, or as a pair of functions that apply a linear operator and its transpose.
19  auto L1_direct = [&L1](t_Vector &out, t_Vector const &input) { out = L1 * input; };
20  auto L1_adjoint = [&L1](t_Vector &out, t_Vector const &input) { out = L1.adjoint() * input; };
21  // Creates the target vectors
22  t_Vector const target0 = t_Vector::Random(N);
23  t_Vector const target1 = t_Vector::Random(N);
24 
25  // Creates the resulting proximal
26  // In practice g_0 and g_1 are any functions with the signature
27  // void(t_Vector &output, t_Vector::Scalar gamma, t_Vector const &input)
28  auto prox_g0 = sopt::proximal::translate(sopt::proximal::EuclidianNorm(), -target0);
29  auto prox_g1 = sopt::proximal::translate(sopt::proximal::EuclidianNorm(), -target1);
30 
31  // This function is called at every iteration. It should return true when convergence is achieved.
32  // Otherwise the convex optimizer will trudge on until the requisite number of iterations have
33  // been achieved.
34  // It takes the convex minimizer and the current candidate output vector as arguments.
35  // The example below assumes convergence when the candidate vector does not change anymore.
36  std::shared_ptr<t_Vector> previous;
37  auto relative = [&previous](t_Vector const &candidate) {
38  if (not previous) {
39  previous = std::make_shared<t_Vector>(candidate);
40  return false;
41  }
42  auto const norm = (*previous - candidate).stableNorm();
43  SOPT_TRACE(" - Checking convergence {}", norm);
44  auto const result = norm < 1e-8 * candidate.size();
45  *previous = candidate;
46  return result;
47  };
48 
49  // Now we can create the sdmm convex minimizer
50  // Its parameters are set by calling member functions with appropriate names.
52  .itermax(500) // maximum number of iterations
53  .gamma(1)
54  .conjugate_gradient(std::numeric_limits<sopt::t_uint>::max(), 1e-12)
55  .is_converged(relative)
56  // Any number of (proximal g_i, L_i) pairs can be added
57  // L_i can be a matrix
58  .append(prox_g0, L0)
59  // L_i can be a pair of functions applying a linear transform and its adjoint
60  .append(prox_g1, L1_direct, L1_adjoint);
61 
62  t_Vector result;
63  t_Vector const input = t_Vector::Random(N);
64  auto const diagnostic = sdmm(result, input);
65 
66  // diagnostic should tell us the function converged
67  // it also contains diagnostic.niters - the number of iterations, and cg_diagnostic - the
68  // diagnostic from the last call to the conjugate gradient.
69  if (not diagnostic.good) throw std::runtime_error("Did not converge!");
70 
71  // Lets test we are at a minimum by recreating the objective function
72  // and checking that stepping in any direction raises its value
73  auto const objective = [&target0, &target1, &L0, &L1](t_Vector const &x) {
74  return (L0 * x - target0).norm() + (L1 * x - target1).norm();
75  };
76  auto const minimum = objective(result);
77  for (int i(0); i < N; ++i) {
78  t_Vector epsilon = t_Vector::Zero(N);
79  epsilon(i) = 1e-4;
80  auto const at_x_plus_epsilon = objective(input + epsilon);
81  if (minimum >= at_x_plus_epsilon) throw std::runtime_error("That's no minimum!");
82  }
83 
84  return 0;
85 }
constexpr auto N
Definition: wavelets.cc:57
sopt::Vector< Scalar > t_Vector
sopt::Matrix< Scalar > t_Matrix
Simultaneous-direction method of the multipliers.
Definition: sdmm.h:23
SDMM< SCALAR > & conjugate_gradient(t_uint itermax, t_real tolerance)
Helps setup conjugate gradient.
Definition: sdmm.h:83
Proximal of euclidian norm.
Definition: proximal.h:18
#define SOPT_TRACE(...)
Definition: logging.h:220
Translation< FUNCTION, VECTOR > translate(FUNCTION const &func, VECTOR const &translation)
Translates given proximal by given vector.
Definition: proximal.h:362
real_type< T >::type epsilon(sopt::LinearTransform< Vector< T >> const &sampling, sopt::Image< T > const &image)
Definition: inpainting.h:38
Eigen::Matrix< T, Eigen::Dynamic, 1 > Vector
A vector of a given type.
Definition: types.h:24
std::complex< t_real > t_complex
Root of the type hierarchy for (real) complex numbers.
Definition: types.h:19
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > Matrix
A matrix of a given type.
Definition: types.h:29

References sopt::algorithm::SDMM< SCALAR >::conjugate_gradient(), sopt::epsilon(), N, SOPT_TRACE, and sopt::proximal::translate().