Applies forward-backward splitting (FBS) to a lasso problem.
Applies forward-backward splitting (FBS) to a lasso problem. Demonstrates the use of the prox_step function.
1#include <alpaqa/example-util.hpp>
5
6#include <algorithm>
7#include <iomanip>
8#include <iostream>
9#include <random>
10#include <tuple>
11using std::cout, std::ranges::generate;
12
13const length_t n = 5;
14
15
16auto build_problem() {
17 auto rng = std::mt19937(12345);
18 auto uni = std::uniform_real_distribution<real_t>(-1, 1);
19 mat A(n, n);
20 vec x(n), b(n);
21 generate(A.reshaped(), [&] { return uni(rng); });
22 generate(x.reshaped(), [&] { return uni(rng); });
23 generate(b.reshaped(), [&] { return 1e-2 * uni(rng); });
24 x(1) = x(3) = 0;
25 b += A * x;
26 real_t λ = 1e-2;
27 return std::make_tuple(std::move(A), std::move(x), std::move(b), λ);
28}
29
31 alpaqa::init_stdout();
32
33
34 auto [A, x_exact, b, λ] = build_problem();
35
37
38 real_t γ = 0.38;
39
40
41 vec x = vec::Zero(n), x_next(n), grad(n), err(n), step(n);
42
43
44 cout << "iteration\t least squares loss\t fixed-point residual\n";
45 for (index_t i = 0; i < 1'000; ++i) {
46
47 err.noalias() = A * x - b;
48 grad.noalias() = A.transpose() * err;
49 real_t f = 0.5 * err.squaredNorm();
50
51
53
54
55 x.swap(x_next);
56
57
58 real_t residual = step.norm() / γ;
59 cout << std::setw(9) << i << '\t' << alpaqa::float_to_str(f) << '\t'
60 << alpaqa::float_to_str(residual) << '\r';
61 if (residual < 1e-10)
62 break;
63 }
64
65
66 cout << '\n';
69}
int main(int argc, const char *argv[])
#define USING_ALPAQA_CONFIG(Conf)
struct alpaqa::prox_step_fn prox_step
Compute a generalized forward-backward step.
std::ostream & print_python(std::ostream &os, const Eigen::DenseBase< Derived > &M)
Double-precision double configuration.