src/subproblem/l1squared_nonneg.rs

Wed, 22 Apr 2026 23:43:00 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Wed, 22 Apr 2026 23:43:00 -0500
branch
dev
changeset 69
3ad8879ee6e1
parent 63
7a8a55fd41c0
child 64
d3be4f7ffd60
permissions
-rw-r--r--

Bump versions

34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1 /*!
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
2 Iterative algorithms for solving the finite-dimensional subproblem with constraint.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
3 */
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
4
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
5 use itertools::izip;
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
6 use nalgebra::DVector;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
7 use numeric_literals::replace_float_literals;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
8 //use std::iter::zip;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
9 use std::cmp::Ordering::*;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
10
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
11 use alg_tools::iterate::{AlgIteratorFactory, AlgIteratorState};
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
12 use alg_tools::nalgebra_support::ToNalgebraRealField;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
13 use alg_tools::norms::{Dist, L1};
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
14
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
15 use super::l1squared_unconstrained::l1squared_prox;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
16 use super::nonneg::nonneg_soft_thresholding;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
17 use super::{InnerMethod, InnerSettings};
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
18 use crate::types::*;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
19
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
20 /// Return maximum of `dist` and distnce of inteval `[lb, ub]` to zero.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
21 #[replace_float_literals(F::cast_from(literal))]
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
22 pub(super) fn max_interval_dist_to_zero<F: Float>(dist: F, lb: F, ub: F) -> F {
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
23 if lb < 0.0 {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
24 if ub > 0.0 {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
25 dist
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
26 } else {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
27 dist.max(-ub)
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
28 }
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
29 } else
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
30 /* ub ≥ 0.0*/
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
31 {
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
32 dist.max(lb)
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
33 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
34 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
35
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
36 /// Returns the ∞-norm minimal subdifferential of $x ↦ (β/2)|x-y|_1^2 - g^⊤ x + λ\|x\|₁ +δ_{≥0}(x)$ at $x$.
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
37 ///
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
38 /// `v` will be modified and cannot be trusted to contain useful values afterwards.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
39 #[replace_float_literals(F::cast_from(literal))]
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
40 fn min_subdifferential<F: Float + nalgebra::RealField>(
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
41 y: &DVector<F>,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
42 x: &DVector<F>,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
43 g: &DVector<F>,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
44 λ: F,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
45 β: F,
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
46 ) -> F {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
47 let mut val = 0.0;
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
48 let tmp = β * y.dist(x, L1);
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
49 for (&g_i, &x_i, y_i) in izip!(g.iter(), x.iter(), y.iter()) {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
50 let (mut lb, mut ub) = (-g_i, -g_i);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
51 match x_i.partial_cmp(y_i) {
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
52 Some(Greater) => {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
53 lb += tmp;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
54 ub += tmp
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
55 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
56 Some(Less) => {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
57 lb -= tmp;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
58 ub -= tmp
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
59 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
60 Some(Equal) => {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
61 lb -= tmp;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
62 ub += tmp
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
63 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
64 None => {}
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
65 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
66 match x_i.partial_cmp(&0.0) {
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
67 Some(Greater) => {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
68 lb += λ;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
69 ub += λ
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
70 }
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
71 // Less should not happen
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
72 Some(Less | Equal) => {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
73 lb = F::NEG_INFINITY;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
74 ub += λ
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
75 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
76 None => {}
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
77 };
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
78 val = max_interval_dist_to_zero(val, lb, ub);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
79 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
80 val
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
81 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
82
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
83 // #[replace_float_literals(F::cast_from(literal))]
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
84 // fn lbd_soft_thresholding<F: Float>(v: F, λ: F, b: F) -> F {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
85 // match (b >= 0.0, v >= b) {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
86 // (true, false) => b,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
87 // (true, true) => b.max(v - λ), // soft-to-b from above
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
88 // (false, true) => super::unconstrained::soft_thresholding(v, λ),
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
89 // (false, false) => 0.0.min(b.max(v + λ)), // soft-to-0 with lower bound
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
90 // }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
91 // }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
92
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
93 /// Calculates $\prox\_f(x)$ for $f(x)=λ\abs{x-y} + δ\_{≥0}(x)$.
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
94 /// This is the first output. The second output is the first output $-y$, i..e, the prox
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
95 /// of $f\_0$ for the shift function $f\_0(z) = f(z+y) = λ\abs{z} + δ\_{≥-y}(z)$
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
96 /// satisfying
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
97 /// $$
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
98 /// \prox_f(x) = \prox\_{f\_0}(x - y) + y,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
99 /// $$
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
100 /// which is also used internally.
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
101 /// The third output indicates whether the output is “locked” to either $0$ (resp. $-y$ in
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
102 /// the reformulation), or $y$ ($0$ in the reformulation).
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
103 /// The fourth output indicates the next highest $λ$ where such locking would happen.
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
104 #[replace_float_literals(F::cast_from(literal))]
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
105 #[inline]
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
106 fn shifted_nonneg_soft_thresholding<F: Float>(x: F, y: F, λ: F) -> (F, F, bool, Option<F>) {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
107 let z = x - y; // The shift to f_0
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
108 if -y >= 0.0 {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
109 if x > λ {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
110 (x - λ, z - λ, false, Some(x))
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
111 } else {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
112 (0.0, -y, true, None)
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
113 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
114 } else if z < 0.0 {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
115 if λ < -x {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
116 (0.0, -y, true, Some(-x))
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
117 } else if z + λ < 0.0 {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
118 (x + λ, z + λ, false, Some(-z))
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
119 } else {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
120 (y, 0.0, true, None)
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
121 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
122 } else if z > λ {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
123 (x - λ, z - λ, false, Some(z))
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
124 } else {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
125 (y, 0.0, true, None)
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
126 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
127 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
128
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
129 /// Calculate $\prox\_f(x)$ for $f(x)=\frac{β}{2}\norm{x-y}\_1\^2 + δ\_{≥0}(x)$.
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
130 ///
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
131 /// To derive an algorithm for this, we can use
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
132 /// $$
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
133 /// \prox_f(x) = \prox\_{f\_0}(x - y) + y
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
134 /// \quad\text{for}\quad
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
135 /// f\_0(z)=\frac{β}{2}\norm{z}\_1\^2 + δ\_{≥-y}(z).
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
136 /// $$
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
137 /// Now, the optimality conditions for $w = \prox\_{f\_0}(x)$ are
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
138 /// $$\tag{*}
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
139 /// x ∈ w + β\norm{w}\_1\sign w + N\_{≥ -y}(w).
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
140 /// $$
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
141 /// If we know $\norm{w}\_1$, then this is easily solved by lower-bounded soft-thresholding.
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
142 /// We find this by sorting the elements by the distance to the 'locked' lower-bounded
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
143 /// soft-thresholding target ($0$ or $-y_i$).
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
144 /// Then we loop over this sorted vector, increasing our estimate of $\norm{w}\_1$ as we decide
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
145 /// that the soft-thresholding parameter $β\norm{w}\_1$ has to be such that the passed elements
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
146 /// will reach their locked value (after which they cannot change anymore, for a larger
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
147 /// soft-thresholding parameter. This has to be slightly more fine-grained for account
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
148 /// for the case that $-y\_i<0$ and $x\_i < -y\_i$.
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
149 ///
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
150 /// Indeed, denoting by $x'$ and $w'$ the subset of elements such that $w\_i ≠ 0$ and
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
151 /// $w\_i > -y\_i$, we can calculate by applying $⟨\cdot, \sign w'⟩$ to the corresponding
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
152 /// lines of (*) that
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
153 /// $$
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
154 /// \norm{x'} = \norm{w'} + β \norm{w}\_1 m,
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
155 /// $$
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
156 /// where $m$ is the number of unlocked components.
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
157 /// We can now calculate the mass $t = \norm{w}-\norm{w'}$ of locked components, and so obtain
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
158 /// $$
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
159 /// \norm{x'} + t = (1+β m)\norm{w}\_1,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
160 /// $$
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
161 /// from where we can calculate the soft-thresholding parameter $λ=β\norm{w}\_1$.
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
162 /// Since we do not actually know the unlocked elements, but just loop over all the possibilities
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
163 /// for them, we have to check that $λ$ is above the current lower bound for this parameter
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
164 /// (`shift` in the code), and below a value that would cause changes in the locked set
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
165 /// (`max_shift` in the code).
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
166 #[replace_float_literals(F::cast_from(literal))]
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
167 pub fn l1squared_nonneg_prox<F: Float + nalgebra::RealField>(
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
168 x: &mut DVector<F>,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
169 y: &DVector<F>,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
170 β: F,
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
171 ) {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
172 // nalgebra double-definition bullshit workaround
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
173 let abs = alg_tools::NumTraitsFloat::abs;
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
174 let min = alg_tools::NumTraitsFloat::min;
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
175
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
176 let mut λ = 0.0;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
177 loop {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
178 let mut w_locked = 0.0;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
179 let mut n_unlocked = 0; // m
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
180 let mut x_prime = 0.0;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
181 let mut max_shift = F::INFINITY;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
182 for (&x_i, &y_i) in izip!(x.iter(), y.iter()) {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
183 let (_, a_shifted, locked, next_lock) = shifted_nonneg_soft_thresholding(x_i, y_i, λ);
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
184
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
185 if let Some(t) = next_lock {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
186 max_shift = min(max_shift, t);
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
187 assert!(max_shift > λ);
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
188 }
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
189 if locked {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
190 w_locked += abs(a_shifted);
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
191 } else {
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
192 n_unlocked += 1;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
193 x_prime += abs(x_i - y_i);
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
194 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
195 }
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
196
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
197 // We need ‖x'‖ = ‖w'‖ + β m ‖w‖, i.e. ‖x'‖ + (‖w‖-‖w'‖)= (1 + β m)‖w‖.
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
198 let λ_new = (x_prime + w_locked) / (1.0 / β + F::cast_from(n_unlocked));
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
199
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
200 if λ_new > max_shift {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
201 λ = max_shift;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
202 } else {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
203 assert!(λ_new >= λ);
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
204 // success
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
205 x.zip_apply(y, |x_i, y_i| {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
206 let (a, _, _, _) = shifted_nonneg_soft_thresholding(*x_i, y_i, λ_new);
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
207 //*x_i = y_i + lbd_soft_thresholding(*x_i, λ_new, -y_i)
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
208 *x_i = a;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
209 });
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
210 return;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
211 }
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
212 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
213 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
214
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
215 /// Proximal point method implementation of [`l1squared_nonneg`].
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
216 /// For detailed documentation of the inputs and outputs, refer to there.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
217 ///
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
218 /// The `λ` component of the model is handled in the proximal step instead of the gradient step
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
219 /// for potential performance improvements.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
220 #[replace_float_literals(F::cast_from(literal).to_nalgebra_mixed())]
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
221 pub fn l1squared_nonneg_pp<F, I>(
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
222 y: &DVector<F::MixedType>,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
223 g: &DVector<F::MixedType>,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
224 λ_: F,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
225 β_: F,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
226 x: &mut DVector<F::MixedType>,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
227 τ_: F,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
228 θ_: F,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
229 iterator: I,
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
230 ) -> usize
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
231 where
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
232 F: Float + ToNalgebraRealField,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
233 I: AlgIteratorFactory<F>,
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
234 {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
235 let λ = λ_.to_nalgebra_mixed();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
236 let β = β_.to_nalgebra_mixed();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
237 let mut τ = τ_.to_nalgebra_mixed();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
238 let θ = θ_.to_nalgebra_mixed();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
239 let mut iters = 0;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
240
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
241 iterator.iterate(|state| {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
242 // Primal step: x^{k+1} = prox_{(τβ/2)|.-y|_1^2+δ_{≥0}+}(x^k - τ(λ𝟙^⊤-g))
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
243 x.apply(|x_i| *x_i -= τ * λ);
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
244 x.axpy(τ, g, 1.0);
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
245 l1squared_nonneg_prox(x, y, τ * β);
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
246
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
247 iters += 1;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
248 // This gives O(1/N^2) rates due to monotonicity of function values.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
249 // Higher acceleration does not seem to be numerically stable.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
250 τ += θ;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
251
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
252 // This gives O(1/N^3) rates due to monotonicity of function values.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
253 // Higher acceleration does not seem to be numerically stable.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
254 //τ + = F::cast_from(iters).to_nalgebra_mixed()*θ;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
255
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
256 state.if_verbose(|| F::from_nalgebra_mixed(min_subdifferential(y, x, g, λ, β)))
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
257 });
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
258
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
259 iters
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
260 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
261
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
262 /// PDPS implementation of [`l1squared_nonneg`].
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
263 /// For detailed documentation of the inputs and outputs, refer to there.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
264 ///
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
265 /// The `λ` component of the model is handled in the proximal step instead of the gradient step
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
266 /// for potential performance improvements.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
267 /// The parameter `θ` is used to multiply the rescale the operator (identity) of the PDPS model.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
268 #[replace_float_literals(F::cast_from(literal).to_nalgebra_mixed())]
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
269 pub fn l1squared_nonneg_pdps<F, I>(
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
270 y: &DVector<F::MixedType>,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
271 g: &DVector<F::MixedType>,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
272 λ_: F,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
273 β_: F,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
274 x: &mut DVector<F::MixedType>,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
275 τ_: F,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
276 σ_: F,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
277 θ_: F,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
278 iterator: I,
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
279 ) -> usize
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
280 where
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
281 F: Float + ToNalgebraRealField,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
282 I: AlgIteratorFactory<F>,
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
283 {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
284 let λ = λ_.to_nalgebra_mixed();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
285 let β = β_.to_nalgebra_mixed();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
286 let τ = τ_.to_nalgebra_mixed();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
287 let σ = σ_.to_nalgebra_mixed();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
288 let θ = θ_.to_nalgebra_mixed();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
289 let mut w = DVector::zeros(x.len());
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
290 let mut tmp = DVector::zeros(x.len());
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
291 let mut xprev = x.clone();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
292 let mut iters = 0;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
293
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
294 iterator.iterate(|state| {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
295 // Primal step: x^{k+1} = prox_{(τβ/2)|.-y|_1^2}(x^k - τ (w^k - g))
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
296 x.axpy(-τ * θ, &w, 1.0);
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
297 x.axpy(τ, g, 1.0);
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
298 l1squared_prox(&mut tmp, x, y, τ * β);
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
299
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
300 // Dual step: w^{k+1} = proj_{[-∞,λ]}(w^k + σ(2x^{k+1}-x^k))
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
301 w.axpy(2.0 * σ * θ, x, 1.0);
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
302 w.axpy(-σ * θ, &xprev, 1.0);
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
303 w.apply(|w_i| *w_i = w_i.min(λ));
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
304 xprev.copy_from(x);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
305
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
306 iters += 1;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
307
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
308 state.if_verbose(|| F::from_nalgebra_mixed(min_subdifferential(y, x, g, λ, β)))
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
309 });
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
310
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
311 iters
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
312 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
313
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
314 /// Alternative PDPS implementation of [`l1squared_nonneg`].
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
315 /// For detailed documentation of the inputs and outputs, refer to there.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
316 ///
42
6a7365d73e4c Fixes to Radon norm prox term inner algorithm
Tuomo Valkonen <tuomov@iki.fi>
parents: 39
diff changeset
317 /// By not dualising the 1-norm, this should produce more sparse solutions than
6a7365d73e4c Fixes to Radon norm prox term inner algorithm
Tuomo Valkonen <tuomov@iki.fi>
parents: 39
diff changeset
318 /// [`l1squared_nonneg_pdps`].
6a7365d73e4c Fixes to Radon norm prox term inner algorithm
Tuomo Valkonen <tuomov@iki.fi>
parents: 39
diff changeset
319 ///
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
320 /// The `λ` component of the model is handled in the proximal step instead of the gradient step
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
321 /// for potential performance improvements.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
322 /// The parameter `θ` is used to multiply the rescale the operator (identity) of the PDPS model.
42
6a7365d73e4c Fixes to Radon norm prox term inner algorithm
Tuomo Valkonen <tuomov@iki.fi>
parents: 39
diff changeset
323 /// We rewrite
6a7365d73e4c Fixes to Radon norm prox term inner algorithm
Tuomo Valkonen <tuomov@iki.fi>
parents: 39
diff changeset
324 /// <div>$$
6a7365d73e4c Fixes to Radon norm prox term inner algorithm
Tuomo Valkonen <tuomov@iki.fi>
parents: 39
diff changeset
325 /// \begin{split}
6a7365d73e4c Fixes to Radon norm prox term inner algorithm
Tuomo Valkonen <tuomov@iki.fi>
parents: 39
diff changeset
326 /// & \min_{x ∈ ℝ^n} \frac{β}{2} |x-y|_1^2 - g^⊤ x + λ\|x\|₁ + δ_{≥ 0}(x) \\
6a7365d73e4c Fixes to Radon norm prox term inner algorithm
Tuomo Valkonen <tuomov@iki.fi>
parents: 39
diff changeset
327 /// & = \min_{x ∈ ℝ^n} \max_{w} ⟨θ w, x⟩ - g^⊤ x + λ\|x\|₁ + δ_{≥ 0}(x)
6a7365d73e4c Fixes to Radon norm prox term inner algorithm
Tuomo Valkonen <tuomov@iki.fi>
parents: 39
diff changeset
328 /// - \left(x ↦ \frac{β}{2θ} |x-y|_1^2 \right)^*(w).
6a7365d73e4c Fixes to Radon norm prox term inner algorithm
Tuomo Valkonen <tuomov@iki.fi>
parents: 39
diff changeset
329 /// \end{split}
6a7365d73e4c Fixes to Radon norm prox term inner algorithm
Tuomo Valkonen <tuomov@iki.fi>
parents: 39
diff changeset
330 /// $$</div>
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
331 #[replace_float_literals(F::cast_from(literal).to_nalgebra_mixed())]
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
332 pub fn l1squared_nonneg_pdps_alt<F, I>(
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
333 y: &DVector<F::MixedType>,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
334 g: &DVector<F::MixedType>,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
335 λ_: F,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
336 β_: F,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
337 x: &mut DVector<F::MixedType>,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
338 τ_: F,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
339 σ_: F,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
340 θ_: F,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
341 iterator: I,
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
342 ) -> usize
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
343 where
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
344 F: Float + ToNalgebraRealField,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
345 I: AlgIteratorFactory<F>,
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
346 {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
347 let λ = λ_.to_nalgebra_mixed();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
348 let τ = τ_.to_nalgebra_mixed();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
349 let σ = σ_.to_nalgebra_mixed();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
350 let θ = θ_.to_nalgebra_mixed();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
351 let β = β_.to_nalgebra_mixed();
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
352 let σθ = σ * θ;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
353 let τθ = τ * θ;
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
354 let mut w = DVector::zeros(x.len());
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
355 let mut tmp = DVector::zeros(x.len());
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
356 let mut xprev = x.clone();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
357 let mut iters = 0;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
358
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
359 iterator.iterate(|state| {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
360 // Primal step: x^{k+1} = nonnegsoft_τλ(x^k - τ(θ w^k -g))
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
361 x.axpy(-τθ, &w, 1.0);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
362 x.axpy(τ, g, 1.0);
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
363 x.apply(|x_i| *x_i = nonneg_soft_thresholding(*x_i, τ * λ));
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
364
42
6a7365d73e4c Fixes to Radon norm prox term inner algorithm
Tuomo Valkonen <tuomov@iki.fi>
parents: 39
diff changeset
365 // Dual step: with g(x) = (β/(2θ))‖x-y‖₁² and q = w^k + σ(2x^{k+1}-x^k),
6a7365d73e4c Fixes to Radon norm prox term inner algorithm
Tuomo Valkonen <tuomov@iki.fi>
parents: 39
diff changeset
366 // we compute w^{k+1} = prox_{σg^*}(q) for
6a7365d73e4c Fixes to Radon norm prox term inner algorithm
Tuomo Valkonen <tuomov@iki.fi>
parents: 39
diff changeset
367 // = q - σ prox_{g/σ}(q/σ)
6a7365d73e4c Fixes to Radon norm prox term inner algorithm
Tuomo Valkonen <tuomov@iki.fi>
parents: 39
diff changeset
368 // = q - σ prox_{(β/(2θσ))‖.-y‖₁²}(q/σ)
6a7365d73e4c Fixes to Radon norm prox term inner algorithm
Tuomo Valkonen <tuomov@iki.fi>
parents: 39
diff changeset
369 // = σ(q/σ - prox_{(β/(2θσ))‖.-y‖₁²}(q/σ))
6a7365d73e4c Fixes to Radon norm prox term inner algorithm
Tuomo Valkonen <tuomov@iki.fi>
parents: 39
diff changeset
370 // where q/σ = w^k/σ + (2x^{k+1}-x^k),
6a7365d73e4c Fixes to Radon norm prox term inner algorithm
Tuomo Valkonen <tuomov@iki.fi>
parents: 39
diff changeset
371 w /= σ;
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
372 w.axpy(2.0, x, 1.0);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
373 w.axpy(-1.0, &xprev, 1.0);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
374 xprev.copy_from(&w); // use xprev as temporary variable
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
375 l1squared_prox(&mut tmp, &mut xprev, y, β / σθ);
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
376 w -= &xprev;
42
6a7365d73e4c Fixes to Radon norm prox term inner algorithm
Tuomo Valkonen <tuomov@iki.fi>
parents: 39
diff changeset
377 w *= σ;
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
378 xprev.copy_from(x);
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
379
42
6a7365d73e4c Fixes to Radon norm prox term inner algorithm
Tuomo Valkonen <tuomov@iki.fi>
parents: 39
diff changeset
380 iters += 1;
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
381
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
382 state.if_verbose(|| F::from_nalgebra_mixed(min_subdifferential(y, x, g, λ, β)))
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
383 });
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
384
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
385 iters
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
386 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
387
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
388 /// This function applies an iterative method for the solution of the problem
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
389 /// <div>$$
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
390 /// \min_{x ∈ ℝ^n} \frac{β}{2} |x-y|_1^2 - g^⊤ x + λ\|x\|₁ + δ_{≥ 0}(x).
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
391 /// $$</div>
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
392 ///
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
393 /// This function returns the number of iterations taken.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
394 #[replace_float_literals(F::cast_from(literal))]
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
395 pub fn l1squared_nonneg<F, I>(
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
396 y: &DVector<F::MixedType>,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
397 g: &DVector<F::MixedType>,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
398 λ: F,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
399 β: F,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
400 x: &mut DVector<F::MixedType>,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
401 inner: &InnerSettings<F>,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
402 iterator: I,
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
403 ) -> usize
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
404 where
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
405 F: Float + ToNalgebraRealField,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
406 I: AlgIteratorFactory<F>,
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
407 {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
408 match inner.method {
39
6316d68b58af Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
409 InnerMethod::PDPS => {
42
6a7365d73e4c Fixes to Radon norm prox term inner algorithm
Tuomo Valkonen <tuomov@iki.fi>
parents: 39
diff changeset
410 let inner_θ = 1.0;
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
411 // Estimate of ‖K‖ for K=θ\Id.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
412 let normest = inner_θ;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
413 let (inner_τ, inner_σ) = (inner.pdps_τσ0.0 / normest, inner.pdps_τσ0.1 / normest);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
414 l1squared_nonneg_pdps_alt(y, g, λ, β, x, inner_τ, inner_σ, inner_θ, iterator)
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
415 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
416 InnerMethod::PP | InnerMethod::FB => {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
417 let inner_τ = inner.pp_τ.0;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
418 let inner_θ = inner.pp_τ.1;
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
419 l1squared_nonneg_pp(y, g, λ, β, x, inner_τ, inner_θ, iterator)
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 42
diff changeset
420 }
39
6316d68b58af Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
421 other => unimplemented!("${other:?} is unimplemented"),
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
422 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
423 }

mercurial