alpaqa cmake-targets
Nonconvex constrained optimization
Loading...
Searching...
No Matches
C++/Advanced/lasso-fbs.cpp

Applies forward-backward splitting (FBS) to a lasso problem.

Applies forward-backward splitting (FBS) to a lasso problem. Demonstrates the use of the alpaqa::prox_step function.

4
5#include <algorithm>
6#include <iomanip>
7#include <iostream>
8#include <random>
9#include <tuple>
10using std::cout, std::ranges::generate;
11
12const length_t n = 5; // problem dimension
13
14// minimize ½‖Ax - b‖² + λ ‖x‖₁
15auto build_problem() {
16 auto rng = std::mt19937(12345);
17 auto uni = std::uniform_real_distribution<real_t>(-1, 1);
18 mat A(n, n);
19 vec x(n), b(n);
20 generate(A.reshaped(), [&] { return uni(rng); });
21 generate(x.reshaped(), [&] { return uni(rng); });
22 generate(b.reshaped(), [&] { return 1e-2 * uni(rng); });
23 x(1) = x(3) = 0;
24 b += A * x;
25 real_t λ = 1e-2;
26 return std::make_tuple(std::move(A), std::move(x), std::move(b), λ);
27}
28
29int main() {
30 // Least squares problem
31 auto [A, x_exact, b, λ] = build_problem();
32 // ℓ₁ regularizer
34 // Step size
35 real_t γ = 0.38; // should be < ‖AᵀA‖₂⁻¹
36
37 // Iterates and other workspace variables
38 vec x = vec::Zero(n), x_next(n), grad(n), err(n), step(n);
39
40 // Forward-backward splitting loop
41 cout << "iteration\t least squares loss\t fixed-point residual\n";
42 for (index_t i = 0; i < 1'000; ++i) {
43 // Compute loss function value and gradient
44 err.noalias() = A * x - b;
45 grad.noalias() = A.transpose() * err;
46 real_t f = 0.5 * err.squaredNorm();
47
48 // Forward-backward step
49 alpaqa::prox_step(h, x, grad, x_next, step, γ, -γ);
50
51 // Advance
52 x.swap(x_next);
53
54 // Check stopping criterion
55 real_t residual = step.norm() / γ;
56 cout << std::setw(9) << i << '\t' << alpaqa::float_to_str(f) << '\t'
57 << alpaqa::float_to_str(residual) << '\r';
58 if (residual < 1e-10)
59 break;
60 }
61
62 // Report solution
63 cout << '\n';
64 alpaqa::print_python(cout << "x_exact = ", x_exact);
65 alpaqa::print_python(cout << "x_lasso = ", x);
66}
int main(int argc, const char *argv[])
#define USING_ALPAQA_CONFIG(Conf)
Definition config.hpp:56
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, Args &&...args)
Definition print.hpp:69
std::string float_to_str(F value, int precision)
Definition print.tpp:67
Double-precision double configuration.
Definition config.hpp:135